diff options
Diffstat (limited to 'konqueror')
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 <[email protected]> +Maintained by David Faure <[email protected]> +Current team : + Simon Hausmann <[email protected]> + Matthias Welk <[email protected]> + Michael Reiher <[email protected]> + Alexander Neundorf <[email protected]> (List views) + Michael Brade <[email protected]> (List Views, I/O lib) + Lars Knoll <[email protected]> (HTML rendering engine) + Antti Koivisto <[email protected]> (HTML rendering engine) + Waldo Bastian <[email protected]> (HTML rendering engine) + Matt Koss <[email protected]> (I/O lib) + Stephan Kulow <[email protected]> (I/O lib) + Richard Moore <[email protected]> (Java applet support) + Dina Rogozin <[email protected]> (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 <[email protected]> + + * Implemented header of vertical toggle views, with support for + a caption text and a close-button + +2001-05-05 David Faure <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * konq_mainwindow.cc (slotReload): call m_currentView->lockHistory(), + to fix #23818 + * konq_view.cc/h (reload): removed obsolete method + +2001-03-31 David Faure <[email protected]> + + * konq_mainwindow.cc(slotRunFinished): Stop wheel animation when a + konqrun fails and we have no view. + +2001-03-25 Simon Hausmann <[email protected]> + + * 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 <[email protected]> + + * konq_view.cc, konq_browseriface.cc/h: Utilize and implement the newly + added KParts::BrowserInterface + +2001-02-06 Simon Hausmann <[email protected]> + + * konq_mainwindow.cc (openBookmarkURL): Patch by + Marco Krohn <[email protected]> to call openFilteredURL + instead of openURL. Allows environment variables in bookmarks and + other sugar. + +2001-01-28 Stephan Kulow <[email protected]> + + * konq_mainwindow.cc (initActions): Plug the actions into a KAccel to + fix short cuts in full screen mode + +2001-01-16 Simon Hausmann <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * konq_dirpart.cc etc.: Always paste to current directory, even + when an item is selected. + +2001-01-12 David Faure <[email protected]> + + * 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 <[email protected]> + + * konq_mainwindow.*, konq_view.*: Store caption in the view, + fixes caption when switching parts or removing one. + +2001-01-11 Carsten Pfeiffer <[email protected]> + + * konq_historymgr.*: KonqHistoryManager now implements the new + HistoryProvider (from KParts) + +2001-01-09 Alexander Neundorf <[email protected]> + + * 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 <[email protected]> + + * KonquerorIface.cc (openBrowserWindow), + (createNewWindow), + (createNewWindow), + (createBrowserWindowFromProfile), + (createBrowserWindowFromProfile), + (createBrowserWindowFromProfileAndURL), + (createBrowserWindowFromProfileAndURL): changed return type from void + to DCOPRef + +2001-01-07 David Faure <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * libkonq/, iconview/: Preview for HTML files implemented. + +2000-12-08 David Faure <[email protected]> and Carsten Pfeiffer <[email protected]> + + * 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 <[email protected]> + + * konq_mainwindow.cc: Turned the Configure submenu into a single dialog. + +2000-12-02 David Faure <[email protected]> + + * 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 <[email protected]> + + * konq_mainwindow.cc: Use current profile in "New Window" to fix #16283. + +2000-11-28 David Faure <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * Views: Implemented in-place renaming of items ("Rename" in menus, F2) + +2000-11-17 David Faure <[email protected]> + + * 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 <[email protected]> + + * konq_viewmgr.cc: Patch by Keunwoo Lee <[email protected]> to + implement dynamic accels for the profile submenu. + +2000-11-15 David Faure <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * libkonq: Implemented "Text preview" functionality + +2000-10-26 David Faure <[email protected]> + + * 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 <[email protected]> + + * 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 <[email protected]> + + * konq_view.{cc,h} : changed part->child( 0, "KParts::BE" ) calls to + use the new childObject method in BrowserExtension + +2000-10-22 David Faure <[email protected]> + + * 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 <[email protected]> + + * Fix for linked views saved in profile, introducing isLoadingProfile(). + +2000-10-20 David Faure <[email protected]> + + * konq_misc.cc: Use webbrowsing profile for *.html *.htm as well. + +2000-10-20 Simon Hausmann <[email protected]> + + * Duplicate window duplicates the history as well. + +[...... long period of development up to KDE 2.0 ommitted .....] + +1999-03-15 Michael Reiher <[email protected]> + + * Implemented an ActiveViewIndicator : KonqFrame + +1999-02-28 Simon Hausmann <[email protected]> + + * Rewrite from scratch, with completely new IDL + +1999-02-09 David Faure <[email protected]> + + * Source imported in kdebase/konqueror + +1999-01-25 Torben Weis <[email protected]> + + * 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, [email protected] + +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 <[email protected]> +To: [email protected] +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 <[email protected]> + 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 <[email protected]> + Copyright (C) 2000 David Faure <[email protected]> + + 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 <[email protected]> + Copyright (C) 2000 David Faure <[email protected]> + + 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 <[email protected]> + Copyright (C) 2000 David Faure <[email protected]> + + 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 <[email protected]> + Copyright (C) 2000 David Faure <[email protected]> + + 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 <[email protected]> + Copyright (C) 2000 David Faure <[email protected]> + + 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 <[email protected]> + Copyright (C) 2000 David Faure <[email protected]> + + 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 Binary files differnew file mode 100644 index 000000000..2bc6e9fa8 --- /dev/null +++ b/konqueror/about/box-centre-konqueror.png 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 %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 & 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>®</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>®</SUP> <A HREF=\"%4\">plugins</A> (for viewing <A HREF=\"%1\">Flash<SUP>®</SUP></A>, <A HREF=\"%2\">Real<SUP>®</SUP></A>Audio, <A HREF=\"%3\">Real<SUP>®</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 & 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"> %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 Binary files differnew file mode 100644 index 000000000..40bfbcfbb --- /dev/null +++ b/konqueror/about/lightning.png 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"> + %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%"> </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"> </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"> </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"> </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"> </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"> </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"> </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"> </td> + <td valign="top">%1<!--built-in--></td> + </tr> + <tr bgcolor="#ffffff"> + <td valign="top">%1<!--AutoCompletion for forms--></td> + <td valign="top"> </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%"> </th> + <th width="58%">%1 <!--Additional requirements*--></th> + </tr> + + <tr bgcolor="#ffffff"> + <td valign="top"> + %1<!--Image formats:--> + </td> + <td valign="top"> </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"> </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"> </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 %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 %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 Binary files differnew file mode 100644 index 000000000..7c4c5ab58 --- /dev/null +++ b/konqueror/about/top-right-konqueror.png 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 <[email protected]> + * if 'exec' has no parameters, popup the Execute Command + dialog from kdesktop + +1999-05-28 Simon Hausmann <[email protected]> + + * use kded instead of the ior file + * use KOMApplication instead of OPApplication (no need for + OpenParts at all) + +1999-04-28 Christophe Prud'homme <[email protected]> + + * 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 <[email protected]> + + 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 <[email protected]> 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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>&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>&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>S&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>&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>&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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 Binary files differnew file mode 100644 index 000000000..6a3fc5efe --- /dev/null +++ b/konqueror/keditbookmarks/cr16-app-keditbookmarks.png diff --git a/konqueror/keditbookmarks/cr32-app-keditbookmarks.png b/konqueror/keditbookmarks/cr32-app-keditbookmarks.png Binary files differnew file mode 100644 index 000000000..b7e10c47f --- /dev/null +++ b/konqueror/keditbookmarks/cr32-app-keditbookmarks.png diff --git a/konqueror/keditbookmarks/cr48-app-keditbookmarks.png b/konqueror/keditbookmarks/cr48-app-keditbookmarks.png Binary files differnew file mode 100644 index 000000000..d1f5e91cc --- /dev/null +++ b/konqueror/keditbookmarks/cr48-app-keditbookmarks.png diff --git a/konqueror/keditbookmarks/cr64-app-keditbookmarks.png b/konqueror/keditbookmarks/cr64-app-keditbookmarks.png Binary files differnew file mode 100644 index 000000000..8f2504942 --- /dev/null +++ b/konqueror/keditbookmarks/cr64-app-keditbookmarks.png 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + * + * 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" ), + "[email protected]" ); + + 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 <[email protected]> + + 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 <[email protected]> + + 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>&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>&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>&View</text> + <Action name="expandall"/> + <Action name="collapseall"/> +</Menu> + +<Menu name="folder"><text>&Folder</text> + <Action name="newfolder"/> + <Action name="insertseparator"/> + <Separator/> + <Action name="sort"/> + <Action name="recursivesort"/> + </Menu> + +<Menu name="bookmark"><text>&Bookmark</text> + <Action name="newbookmark"/> +</Menu> + +<Menu name="settings"><text>&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>&File</text> + <Action name="file_open"/> + <Action name="file_save_as"/> + <Separator/> + <Action name="file_print"/> + <Separator/> + <Menu name="import" noMerge="1"><text>&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>&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>&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>&View</text> + <Action name="expandall"/> + <Action name="collapseall"/> +</Menu> + +<Menu name="folder"><text>&Folder</text> + <Action name="newfolder"/> + <Action name="insertseparator"/> + <Separator/> + <Action name="setastoolbar"/> + <Action name="sort"/> + <Action name="recursivesort"/> + </Menu> + +<Menu name="bookmark"><text>&Bookmark</text> + <Action name="newbookmark"/> + <Action name="openlink"/> + <Separator/> + <Action name="testlink"/> + <Action name="updatefavicon"/> +</Menu> + +<Menu name="tools"><text>&Tools</text> + <Action name="testall"/> + <Action name="canceltests"/> + <Separator/> + <Action name="updateallfavicons"/> + <Action name="cancelfaviconupdates"/> +</Menu> + +<Menu name="settings"><text>&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 <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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"), "[email protected]"); + aboutData.addAuthor("Alexander Kellett", I18N_NOOP("Author"), "[email protected]"); + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + Copyright (C) 2002-2003 Alexander Kellett <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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>&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>&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>&View</text> + <Action name="go_most_often" /> + <ActionList name="viewmode" /> + <Separator/> + <Merge/> + </Menu> + <Action name="bookmarks" /> + <Menu name="tools" > + <text>&Tools</text> + <WeakSeparator/> + <Merge/> + </Menu> + <Menu noMerge="1" name="settings" > + <text>&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>&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 <[email protected]> + + 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 <[email protected]> + + 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 <[email protected]> + + 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 ± } + + 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 <[email protected]> + + 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 KONQ_COMBO_H +#define KONQ_COMBO_H + +#include <qevent.h> + +#include <kcombobox.h> +#include <konq_historymgr.h> + +class KCompletion; +class KConfig; + +// we use KHistoryCombo _only_ for the up/down keyboard handling, otherwise +// KComboBox would do fine. +class KonqCombo : public KHistoryCombo +{ + Q_OBJECT + +public: + KonqCombo( QWidget *parent, const char *name ); + ~KonqCombo(); + + // initializes with the completion object and calls loadItems() + void init( KCompletion * ); + + // determines internally if it's temporary or final + void setURL( const QString& url ); + + void setTemporary( const QString& ); + void setTemporary( const QString&, const QPixmap& ); + void clearTemporary( bool makeCurrent = true ); + void removeURL( const QString& url ); + + void insertPermanent( const QString& ); + + void updatePixmaps(); + + void loadItems(); + void saveItems(); + + static void setConfig( KConfig * ); + + virtual void popup(); + + void setPageSecurity( int ); + + void insertItem( const QString &text, int index=-1, const QString& title=QString::null ); + void insertItem( const QPixmap &pixmap, const QString &text, int index=-1, const QString& title=QString::null ); + +protected: + virtual void keyPressEvent( QKeyEvent * ); + virtual bool eventFilter( QObject *, QEvent * ); + virtual void mousePressEvent( QMouseEvent * ); + virtual void mouseMoveEvent( QMouseEvent * ); + void paintEvent( QPaintEvent * ); + void selectWord(QKeyEvent *e); + +signals: + /** + Specialized signal that emits the state of the modifier + keys along with the actual activated text. + */ + void activated( const QString &, int ); + + /** + User has clicked on the security lock in the combobar + */ + void showPageSecurity(); + +private slots: + void slotCleared(); + void slotSetIcon( int index ); + void slotActivated( const QString& text ); + +private: + void updateItem( const QPixmap& pix, const QString&, int index, const QString& title ); + void saveState(); + void restoreState(); + void applyPermanent(); + QString temporaryItem() const { return text( temporary ); } + void removeDuplicates( int index ); + bool hasSufficientContrast(const QColor &c1, const QColor &c2); + + bool m_returnPressed; + bool m_permanent; + int m_cursorPos; + int m_currentIndex; + int m_modifier; + QString m_currentText; + QPoint m_dragStart; + int m_pageSecurity; + + static KConfig *s_config; + static const int temporary; // the index of our temporary item +}; + +#endif // KONQ_COMBO_H diff --git a/konqueror/konq_extensionmanager.cc b/konqueror/konq_extensionmanager.cc new file mode 100644 index 000000000..a43d4540d --- /dev/null +++ b/konqueror/konq_extensionmanager.cc @@ -0,0 +1,147 @@ +/* -*- indent-tabs-mode: t; tab-width: 4; c-basic-offset:4 -*- + konq_extensionmanager.cc - Extension Manager for Konqueror + + Copyright (c) 2003 by Martijn Klingens <[email protected]> + Copyright (c) 2004 by Arend van Beelen jr. <[email protected]> + + ************************************************************************* + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ************************************************************************* +*/ + +#include <qlayout.h> +#include <qtimer.h> + +#include <kconfig.h> +#include <kdebug.h> +#include <klocale.h> +#include <kparts/componentfactory.h> +#include <kparts/plugin.h> +#include <kplugininfo.h> +#include <kpluginselector.h> +#include <ksettings/dispatcher.h> +#include <dcopref.h> + +#include "konq_extensionmanager.h" +#include "konq_mainwindow.h" + +class KonqExtensionManagerPrivate +{ +public: + KPluginSelector *pluginSelector; + KonqMainWindow *mainWindow; + KParts::ReadOnlyPart* activePart; + bool isChanged; +}; + +KonqExtensionManager::KonqExtensionManager(QWidget *parent, KonqMainWindow *mainWindow, KParts::ReadOnlyPart* activePart) : + KDialogBase(Plain, i18n("Configure"), Default | Cancel | Apply | Ok | User1, + Ok, parent, "extensionmanager", false, true, KGuiItem(i18n("&Reset"), "undo")) +{ + d = new KonqExtensionManagerPrivate; + showButton(User1, false); + setChanged(false); + + setInitialSize(QSize(640, 480)); + + (new QVBoxLayout(plainPage(), 0, 0))->setAutoAdd(true); + d->pluginSelector = new KPluginSelector(plainPage()); + setMainWidget(d->pluginSelector); + connect(d->pluginSelector, SIGNAL(changed(bool)), this, SLOT(setChanged(bool))); + connect(d->pluginSelector, SIGNAL(configCommitted(const QCString &)), + KSettings::Dispatcher::self(), SLOT(reparseConfiguration(const QCString &))); + + d->mainWindow = mainWindow; + d->activePart = activePart; + + // There's a limitation of KPluginSelector here... It assumes that all plugins in a given widget (as created by addPlugins) + // have their config in the same KConfig[Group]. So we can't show konqueror extensions and khtml extensions in the same tab. + d->pluginSelector->addPlugins("konqueror", i18n("Extensions"), "Extensions", KGlobal::config()); + if ( activePart ) { + KInstance* instance = activePart->instance(); + d->pluginSelector->addPlugins(instance->instanceName(), i18n("Tools"), "Tools", instance->config()); + d->pluginSelector->addPlugins(instance->instanceName(), i18n("Statusbar"), "Statusbar", instance->config()); + } +} + +KonqExtensionManager::~KonqExtensionManager() +{ + delete d; +} + +void KonqExtensionManager::setChanged(bool c) +{ + d->isChanged = c; + enableButton(Apply, c); +} + +void KonqExtensionManager::slotDefault() +{ + d->pluginSelector->defaults(); + setChanged(false); +} + +void KonqExtensionManager::slotUser1() +{ + d->pluginSelector->load(); + setChanged(false); +} + +void KonqExtensionManager::apply() +{ + if(d->isChanged) + { + d->pluginSelector->save(); + setChanged(false); + if( d->mainWindow ) + { + KParts::Plugin::loadPlugins(d->mainWindow, d->mainWindow, KGlobal::instance()); + QPtrList<KParts::Plugin> plugins = KParts::Plugin::pluginObjects(d->mainWindow); + QPtrListIterator<KParts::Plugin> it(plugins); + KParts::Plugin *plugin; + while((plugin = it.current()) != 0) + { + ++it; + d->mainWindow->factory()->addClient(plugin); + } + } + if ( d->activePart ) + { + KParts::Plugin::loadPlugins( d->activePart, d->activePart, d->activePart->instance() ); + QPtrList<KParts::Plugin> plugins = KParts::Plugin::pluginObjects( d->activePart ); + QPtrListIterator<KParts::Plugin> it(plugins); + KParts::Plugin *plugin; + while((plugin = it.current()) != 0) + { + ++it; + d->activePart->factory()->addClient(plugin); + } + } + } +} + +void KonqExtensionManager::slotApply() +{ + apply(); +} + +void KonqExtensionManager::slotOk() +{ + emit okClicked(); + apply(); + accept(); +} + +void KonqExtensionManager::show() +{ + d->pluginSelector->load(); + + KDialogBase::show(); +} + +#include "konq_extensionmanager.moc" diff --git a/konqueror/konq_extensionmanager.h b/konqueror/konq_extensionmanager.h new file mode 100644 index 000000000..824dc2771 --- /dev/null +++ b/konqueror/konq_extensionmanager.h @@ -0,0 +1,57 @@ +/* -*- indent-tabs-mode: t; tab-width: 4; c-basic-offset:4 -*- + + konq_extensionmanager.h - Extension Manager for Konqueror + + Copyright (c) 2003 by Martijn Klingens <[email protected]> + Copyright (c) 2004 by Arend van Beelen jr. <[email protected]> + + ************************************************************************* + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ************************************************************************* +*/ + +#ifndef KONQEXTENSIONMANAGER_H +#define KONQEXTENSIONMANAGER_H + +#include <kdialogbase.h> + +class KonqExtensionManagerPrivate; +class KonqMainWindow; +namespace KParts { class ReadOnlyPart; } + +/** + * Extension Manager for Konqueror. See KPluginSelector in kdelibs for + * documentation. + * + * @author Martijn Klingens <[email protected]> + * @author Arend van Beelen jr. <[email protected]> + */ +class KonqExtensionManager : public KDialogBase +{ + Q_OBJECT + + public: + KonqExtensionManager(QWidget *parent, KonqMainWindow *mainWindow, KParts::ReadOnlyPart* activePart); + ~KonqExtensionManager(); + + void apply(); + + public slots: + void setChanged(bool c); + + virtual void slotDefault(); + virtual void slotUser1(); + virtual void slotApply(); + virtual void slotOk(); + virtual void show(); + + private: + KonqExtensionManagerPrivate *d; +}; + +#endif // KONQEXTENSIONMANAGER_H diff --git a/konqueror/konq_factory.cc b/konqueror/konq_factory.cc new file mode 100644 index 000000000..c873fcee9 --- /dev/null +++ b/konqueror/konq_factory.cc @@ -0,0 +1,263 @@ +/* This file is part of the KDE project + Copyright (C) 1999 Simon Hausmann <[email protected]> + Copyright (C) 1999 David Faure <[email protected]> + Copyright (C) 1999 Torben Weis <[email protected]> + + 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. + +*/ + +#include <kparts/factory.h> +#include "konq_factory.h" +#include "version.h" + +#include <konq_settings.h> +#include <konq_mainwindow.h> +#include <kdebug.h> +#include <kaboutdata.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include <qwidget.h> +#include <qfile.h> + +#include <assert.h> + +KAboutData *KonqFactory::s_aboutData = 0; + +KonqViewFactory::KonqViewFactory( KLibFactory *factory, const QStringList &args, + bool createBrowser ) + : m_factory( factory ), m_args( args ), m_createBrowser( createBrowser ) +{ + if ( m_createBrowser ) + m_args << QString::fromLatin1( "Browser/View" ); +} + +KParts::ReadOnlyPart *KonqViewFactory::create( QWidget *parentWidget, const char *widgetName, + QObject * parent, const char *name ) +{ + if ( !m_factory ) + return 0L; + + QObject *obj = 0L; + + if ( m_factory->inherits( "KParts::Factory" ) ) + { + if ( m_createBrowser ) + obj = static_cast<KParts::Factory *>(m_factory)->createPart( parentWidget, widgetName, parent, name, "Browser/View", m_args ); + + if ( !obj ) + obj = static_cast<KParts::Factory *>(m_factory)->createPart( parentWidget, widgetName, parent, name, "KParts::ReadOnlyPart", m_args ); + } + else + { + if ( m_createBrowser ) + obj = m_factory->create( parentWidget, name, "Browser/View", m_args ); + + if ( !obj ) + obj = m_factory->create( parentWidget, name, "KParts::ReadOnlyPart", m_args ); + } + + if ( !obj->inherits( "KParts::ReadOnlyPart" ) ) + kdError(1202) << "Part " << obj << " (" << obj->className() << ") doesn't inherit KParts::ReadOnlyPart !" << endl; + + KParts::ReadOnlyPart* part = static_cast<KParts::ReadOnlyPart *>( obj ); + QFrame* frame = ::qt_cast<QFrame*>( part->widget() ); + if (frame) + { + frame->setFrameStyle( QFrame::NoFrame ); + } + + return part; +} + +KonqViewFactory KonqFactory::createView( const QString &serviceType, + const QString &serviceName, + KService::Ptr *serviceImpl, + KTrader::OfferList *partServiceOffers, + KTrader::OfferList *appServiceOffers, + bool forceAutoEmbed ) +{ + kdDebug(1202) << "Trying to create view for \"" << serviceType << "\"" << endl; + + // We need to get those in any case + KTrader::OfferList offers, appOffers; + + // Query the trader + getOffers( serviceType, &offers, &appOffers ); + + if ( partServiceOffers ) + (*partServiceOffers) = offers; + if ( appServiceOffers ) + (*appServiceOffers) = appOffers; + + // We ask ourselves whether to do it or not only if no service was specified. + // If it was (from the View menu or from RMB + Embedding service), just do it. + forceAutoEmbed = forceAutoEmbed || !serviceName.isEmpty(); + // Or if we have no associated app anyway, then embed. + forceAutoEmbed = forceAutoEmbed || ( appOffers.isEmpty() && !offers.isEmpty() ); + // Or if the associated app is konqueror itself, then embed. + if ( !appOffers.isEmpty() ) + forceAutoEmbed = forceAutoEmbed || KonqMainWindow::isMimeTypeAssociatedWithSelf( serviceType, appOffers.first() ); + + if ( ! forceAutoEmbed ) + { + if ( ! KonqFMSettings::settings()->shouldEmbed( serviceType ) ) + { + kdDebug(1202) << "KonqFMSettings says: don't embed this servicetype" << endl; + return KonqViewFactory(); + } + } + + KService::Ptr service = 0L; + + // Look for this service + if ( !serviceName.isEmpty() ) + { + KTrader::OfferList::Iterator it = offers.begin(); + for ( ; it != offers.end() && !service ; ++it ) + { + if ( (*it)->desktopEntryName() == serviceName ) + { + kdDebug(1202) << "Found requested service " << serviceName << endl; + service = *it; + } + } + } + + KLibFactory *factory = 0L; + + if ( service ) + { + kdDebug(1202) << "Trying to open lib for requested service " << service->desktopEntryName() << endl; + factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) ); + if ( !factory ) + KMessageBox::error(0, + i18n("There was an error loading the module %1.\nThe diagnostics is:\n%2") + .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage())); + } + + KTrader::OfferList::Iterator it = offers.begin(); + for ( ; !factory && it != offers.end() ; ++it ) + { + service = (*it); + // Allowed as default ? + QVariant prop = service->property( "X-KDE-BrowserView-AllowAsDefault" ); + kdDebug(1202) << service->desktopEntryName() << " : X-KDE-BrowserView-AllowAsDefault is valid : " << prop.isValid() << endl; + if ( !prop.isValid() || prop.toBool() ) // defaults to true + { + //kdDebug(1202) << "Trying to open lib for service " << service->name() << endl; + // Try loading factory + factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) ); + if ( !factory ) + KMessageBox::error(0, + i18n("There was an error loading the module %1.\nThe diagnostics is:\n%2") + .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage())); + // If this works, we exit the loop. + } else + kdDebug(1202) << "Not allowed as default " << service->desktopEntryName() << endl; + } + + if ( serviceImpl ) + (*serviceImpl) = service; + + if ( !factory ) + { + kdWarning(1202) << "KonqFactory::createView : no factory" << endl; + return KonqViewFactory(); + } + + QStringList args; + + QVariant prop = service->property( "X-KDE-BrowserView-Args" ); + + if ( prop.isValid() ) + { + QString argStr = prop.toString(); + args = QStringList::split( " ", argStr ); + } + + return KonqViewFactory( factory, args, service->serviceTypes().contains( "Browser/View" ) ); +} + +void KonqFactory::getOffers( const QString & serviceType, + KTrader::OfferList *partServiceOffers, + KTrader::OfferList *appServiceOffers ) +{ + if ( appServiceOffers ) + { + *appServiceOffers = KTrader::self()->query( serviceType, "Application", +"DesktopEntryName != 'kfmclient' and DesktopEntryName != 'kfmclient_dir' and DesktopEntryName != 'kfmclient_html'", + QString::null ); + } + + if ( partServiceOffers ) + { + *partServiceOffers = KTrader::self()->query( serviceType, "KParts/ReadOnlyPart", + QString::null, QString::null ); + } +} + + +const KAboutData *KonqFactory::aboutData() +{ + if (!s_aboutData) + { + s_aboutData = new KAboutData( "konqueror", I18N_NOOP("Konqueror"), + KONQUEROR_VERSION, + I18N_NOOP("Web browser, file manager, ..."), + KAboutData::License_GPL, + I18N_NOOP("(c) 1999-2005, The Konqueror developers"), + 0, + I18N_NOOP("http://konqueror.kde.org") ); + s_aboutData->addAuthor( "David Faure", I18N_NOOP("developer (framework, parts, JavaScript, I/O lib) and maintainer"), "[email protected]" ); + s_aboutData->addAuthor( "Simon Hausmann", I18N_NOOP("developer (framework, parts)"), "[email protected]" ); + s_aboutData->addAuthor( "Michael Reiher", I18N_NOOP("developer (framework)"), "[email protected]" ); + s_aboutData->addAuthor( "Matthias Welk", I18N_NOOP("developer"), "[email protected]" ); + s_aboutData->addAuthor( "Alexander Neundorf", I18N_NOOP("developer (List views)"), "[email protected]" ); + s_aboutData->addAuthor( "Michael Brade", I18N_NOOP("developer (List views, I/O lib)"), "[email protected]" ); + s_aboutData->addAuthor( "Lars Knoll", I18N_NOOP("developer (HTML rendering engine)"), "[email protected]" ); + s_aboutData->addAuthor( "Dirk Mueller", I18N_NOOP("developer (HTML rendering engine)"), "[email protected]" ); + s_aboutData->addAuthor( "Peter Kelly", I18N_NOOP("developer (HTML rendering engine)"), "[email protected]" ); + s_aboutData->addAuthor( "Waldo Bastian", I18N_NOOP("developer (HTML rendering engine, I/O lib)"), "[email protected]" ); + s_aboutData->addAuthor( "Germain Garand", I18N_NOOP("developer (HTML rendering engine)"), "[email protected]" ); + s_aboutData->addAuthor( "Leo Savernik", I18N_NOOP("developer (HTML rendering engine)"), "[email protected]" ); + s_aboutData->addAuthor( "Stephan Kulow", I18N_NOOP("developer (HTML rendering engine, I/O lib, regression test framework)"), "[email protected]" ); + s_aboutData->addAuthor( "Antti Koivisto", I18N_NOOP("developer (HTML rendering engine)"), "[email protected]" ); + s_aboutData->addAuthor( "Zack Rusin", I18N_NOOP("developer (HTML rendering engine)"), "[email protected]" ); + s_aboutData->addAuthor( "Tobias Anton", I18N_NOOP( "developer (HTML rendering engine)" ), "[email protected]" ); + s_aboutData->addAuthor( "Lubos Lunak", I18N_NOOP( "developer (HTML rendering engine)" ), "[email protected]" ); + s_aboutData->addAuthor( "Allan Sandfeld Jensen", I18N_NOOP( "developer (HTML rendering engine)" ), "[email protected]" ); + s_aboutData->addAuthor( "Apple Safari Developers", I18N_NOOP("developer (HTML rendering engine, JavaScript)"), "" ); + s_aboutData->addAuthor( "Harri Porten", I18N_NOOP("developer (JavaScript)"), "[email protected]" ); + s_aboutData->addAuthor( "Koos Vriezen", I18N_NOOP("developer (Java applets and other embedded objects)"), "[email protected]" ); + s_aboutData->addAuthor( "Matt Koss", I18N_NOOP("developer (I/O lib)"), "[email protected]" ); + s_aboutData->addAuthor( "Alex Zepeda", I18N_NOOP("developer (I/O lib)"), "[email protected]" ); + s_aboutData->addAuthor( "Richard Moore", I18N_NOOP("developer (Java applet support)"), "[email protected]" ); + s_aboutData->addAuthor( "Dima Rogozin", I18N_NOOP("developer (Java applet support)"), "[email protected]" ); + s_aboutData->addAuthor( "Wynn Wilkes", I18N_NOOP("developer (Java 2 security manager support,\n and other major improvements to applet support)"), "[email protected]" ); + s_aboutData->addAuthor( "Stefan Schimanski", I18N_NOOP("developer (Netscape plugin support)"), "[email protected]" ); + s_aboutData->addAuthor( "George Staikos", I18N_NOOP("developer (SSL, Netscape plugins)"), "[email protected]" ); + s_aboutData->addAuthor( "Dawit Alemayehu",I18N_NOOP("developer (I/O lib, Authentication support)"), "[email protected]" ); + s_aboutData->addAuthor( "Carsten Pfeiffer",I18N_NOOP("developer (framework)"), "[email protected]" ); + s_aboutData->addAuthor( "Torsten Rahn", I18N_NOOP("graphics/icons"), "[email protected]" ); + s_aboutData->addAuthor( "Torben Weis", I18N_NOOP("kfm author"), "[email protected]" ); + s_aboutData->addAuthor( "Joseph Wenninger", I18N_NOOP("developer (navigation panel framework)"),"[email protected]"); + s_aboutData->addAuthor( "Stephan Binner", I18N_NOOP("developer (misc stuff)"),"[email protected]"); + s_aboutData->addAuthor( "Ivor Hewitt", I18N_NOOP("developer (AdBlock filter)"),"[email protected]"); + } + return s_aboutData; +} + diff --git a/konqueror/konq_factory.h b/konqueror/konq_factory.h new file mode 100644 index 000000000..8d156876f --- /dev/null +++ b/konqueror/konq_factory.h @@ -0,0 +1,86 @@ +/* This file is part of the KDE project + Copyright (C) 1999 Simon Hausmann <[email protected]> + Copyright (C) 1999 David Faure <[email protected]> + Copyright (C) 1999 Torben Weis <[email protected]> + + 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_factory_h__ +#define __konq_factory_h__ + +#include <qstring.h> +#include <qstringlist.h> + +#include <klibloader.h> +#include <ktrader.h> + +#include <kparts/part.h> + +class BrowserView; +class KonqMainWindow; +class KAboutData; + +class KonqViewFactory +{ +public: + KonqViewFactory() : m_factory( 0L ), m_createBrowser( false ) {} + + KonqViewFactory( KLibFactory *factory, const QStringList &args, bool createBrowser ); + + KonqViewFactory( const KonqViewFactory &factory ) + { (*this) = factory; } + + KonqViewFactory &operator=( const KonqViewFactory &other ) + { + m_factory = other.m_factory; + m_args = other.m_args; + m_createBrowser = other.m_createBrowser; + return *this; + } + + KParts::ReadOnlyPart *create( QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name ); + + bool isNull() const { return m_factory ? false : true; } + +private: + KLibFactory *m_factory; + QStringList m_args; + bool m_createBrowser; +}; + +class KonqFactory +{ +public: + static KonqViewFactory createView( const QString &serviceType, + const QString &serviceName = QString::null, + KService::Ptr *serviceImpl = 0, + KTrader::OfferList *partServiceOffers = 0, + KTrader::OfferList *appServiceOffers = 0, + bool forceAutoEmbed = false ); + + static void getOffers( const QString & serviceType, + KTrader::OfferList *partServiceOffers = 0, + KTrader::OfferList *appServiceOffers = 0); + + static const KAboutData* aboutData(); + +private: + static KAboutData *s_aboutData; +}; + +#endif diff --git a/konqueror/konq_frame.cc b/konqueror/konq_frame.cc new file mode 100644 index 000000000..0aacbe3d6 --- /dev/null +++ b/konqueror/konq_frame.cc @@ -0,0 +1,670 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Michael Reiher <[email protected]> + + 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 <math.h> + +#include <qpainter.h> +#include <qlayout.h> +#include <qwhatsthis.h> +#include <qtoolbutton.h> +#include <qtabbar.h> +#include <qptrlist.h> +#include <qpopupmenu.h> +#include <qkeysequence.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <kprogress.h> +#include <klocale.h> +#include <ksqueezedtextlabel.h> + +#include "konq_events.h" +#include "konq_frame.h" +#include "konq_tabs.h" +#include "konq_view.h" +#include "konq_viewmgr.h" + +#include <konq_pixmapprovider.h> +#include <kstdaccel.h> +#include <assert.h> + + +#define DEFAULT_HEADER_HEIGHT 13 + +void KonqCheckBox::drawButton( QPainter *p ) +{ + //static QPixmap indicator_anchor( UserIcon( "indicator_anchor" ) ); + static QPixmap indicator_connect( UserIcon( "indicator_connect" ) ); + static QPixmap indicator_noconnect( UserIcon( "indicator_noconnect" ) ); + + if (isOn() || isDown()) + p->drawPixmap(0,0,indicator_connect); + else + p->drawPixmap(0,0,indicator_noconnect); +} + +KonqFrameStatusBar::KonqFrameStatusBar( KonqFrame *_parent, const char *_name ) + : KStatusBar( _parent, _name ), + m_pParentKonqFrame( _parent ) +{ + setSizeGripEnabled( false ); + + m_led = new QLabel( this ); + m_led->setAlignment( Qt::AlignCenter ); + m_led->setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed )); + addWidget( m_led, 0, false ); // led (active view indicator) + m_led->hide(); + + m_pStatusLabel = new KSqueezedTextLabel( this ); + m_pStatusLabel->setMinimumSize( 0, 0 ); + m_pStatusLabel->setSizePolicy(QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed )); + m_pStatusLabel->installEventFilter(this); + addWidget( m_pStatusLabel, 1 /*stretch*/, false ); // status label + + m_pLinkedViewCheckBox = new KonqCheckBox( this, "m_pLinkedViewCheckBox" ); + m_pLinkedViewCheckBox->setFocusPolicy(NoFocus); + m_pLinkedViewCheckBox->setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed )); + QWhatsThis::add( m_pLinkedViewCheckBox, + i18n("Checking this box on at least two views sets those views as 'linked'. " + "Then, when you change directories in one view, the other views " + "linked with it will automatically update to show the current directory. " + "This is especially useful with different types of views, such as a " + "directory tree with an icon view or detailed view, and possibly a " + "terminal emulator window." ) ); + addWidget( m_pLinkedViewCheckBox, 0, true /*permanent->right align*/ ); + connect( m_pLinkedViewCheckBox, SIGNAL(toggled(bool)), + this, SIGNAL(linkedViewClicked(bool)) ); + + m_progressBar = new KProgress( this ); + m_progressBar->setMaximumHeight(fontMetrics().height()); + m_progressBar->hide(); + addWidget( m_progressBar, 0, true /*permanent->right align*/ ); + + fontChange(QFont()); + installEventFilter( this ); +} + +KonqFrameStatusBar::~KonqFrameStatusBar() +{ +} + +void KonqFrameStatusBar::fontChange(const QFont & /* oldFont */) +{ + int h = fontMetrics().height(); + if ( h < DEFAULT_HEADER_HEIGHT ) h = DEFAULT_HEADER_HEIGHT; + m_led->setFixedHeight( h + 2 ); + m_progressBar->setFixedHeight( h + 2 ); + // This one is important. Otherwise richtext messages make it grow in height. + m_pStatusLabel->setFixedHeight( h + 2 ); + +} + +void KonqFrameStatusBar::resizeEvent( QResizeEvent* ev ) +{ + //m_progressBar->setGeometry( width()-160, 0, 140, height() ); + //m_pLinkedViewCheckBox->move( width()-15, m_yOffset ); // right justify + KStatusBar::resizeEvent( ev ); +} + +// I don't think this code _ever_ gets called! +// I don't want to remove it, though. :-) +void KonqFrameStatusBar::mousePressEvent( QMouseEvent* event ) +{ + QWidget::mousePressEvent( event ); + if ( !m_pParentKonqFrame->childView()->isPassiveMode() ) + { + emit clicked(); + update(); + } + + //Blocks menu of custom status bar entries + //if (event->button()==RightButton) + // splitFrameMenu(); +} + +void KonqFrameStatusBar::splitFrameMenu() +{ + KonqMainWindow * mw = m_pParentKonqFrame->childView()->mainWindow(); + + // We have to ship the remove view action ourselves, + // since this may not be the active view (passive view) + KAction actRemoveView(i18n("Close View"), "view_remove", 0, m_pParentKonqFrame, SLOT(slotRemoveView()), (QObject*)0, "removethisview"); + //KonqView * nextView = mw->viewManager()->chooseNextView( m_pParentKonqFrame->childView() ); + actRemoveView.setEnabled( mw->mainViewsCount() > 1 || m_pParentKonqFrame->childView()->isToggleView() || m_pParentKonqFrame->childView()->isPassiveMode() ); + + // For the rest, we borrow them from the main window + // ###### might be not right for passive views ! + KActionCollection *actionColl = mw->actionCollection(); + + QPopupMenu menu; + + actionColl->action( "splitviewh" )->plug( &menu ); + actionColl->action( "splitviewv" )->plug( &menu ); + menu.insertSeparator(); + actionColl->action( "lock" )->plug( &menu ); + + actRemoveView.plug( &menu ); + + menu.exec(QCursor::pos()); +} + +bool KonqFrameStatusBar::eventFilter(QObject* o, QEvent *e) +{ + if (o == m_pStatusLabel && e->type()==QEvent::MouseButtonPress) + { + emit clicked(); + update(); + if ( static_cast<QMouseEvent *>(e)->button() == RightButton) + splitFrameMenu(); + return true; + } + else if ( o == this && e->type() == QEvent::ApplicationPaletteChange ) + { + unsetPalette(); + updateActiveStatus(); + return true; + } + + return false; +} + +void KonqFrameStatusBar::message( const QString &msg ) +{ + // We don't use the message()/clear() mechanism of QStatusBar because + // it really looks ugly (the label border goes away, the active-view indicator + // is hidden...) + QString saveMsg = m_savedMessage; + slotDisplayStatusText( msg ); + m_savedMessage = saveMsg; +} + +void KonqFrameStatusBar::slotDisplayStatusText(const QString& text) +{ + //kdDebug(1202)<<"KonqFrameHeader::slotDisplayStatusText("<<text<<")"<<endl; + //m_pStatusLabel->resize(fontMetrics().width(text),fontMetrics().height()+2); + m_pStatusLabel->setText(text); + m_savedMessage = text; +} + +void KonqFrameStatusBar::slotClear() +{ + slotDisplayStatusText( m_savedMessage ); +} + +void KonqFrameStatusBar::slotLoadingProgress( int percent ) +{ + if ( percent != -1 && percent != 100 ) // hide on 100 too + { + if ( !m_progressBar->isVisible() ) + m_progressBar->show(); + } + else + m_progressBar->hide(); + + m_progressBar->setValue( percent ); +} + +void KonqFrameStatusBar::slotSpeedProgress( int bytesPerSecond ) +{ + QString sizeStr; + + if ( bytesPerSecond > 0 ) + sizeStr = i18n( "%1/s" ).arg( KIO::convertSize( bytesPerSecond ) ); + else + sizeStr = i18n( "Stalled" ); + + slotDisplayStatusText( sizeStr ); // let's share the same label... +} + +void KonqFrameStatusBar::slotConnectToNewView(KonqView *, KParts::ReadOnlyPart *,KParts::ReadOnlyPart *newOne) +{ + if (newOne!=0) + connect(newOne,SIGNAL(setStatusBarText(const QString &)),this,SLOT(slotDisplayStatusText(const QString&))); + slotDisplayStatusText( QString::null ); +} + +void KonqFrameStatusBar::showActiveViewIndicator( bool b ) +{ + m_led->setShown( b ); + updateActiveStatus(); +} + +void KonqFrameStatusBar::showLinkedViewIndicator( bool b ) +{ + m_pLinkedViewCheckBox->setShown( b ); +} + +void KonqFrameStatusBar::setLinkedView( bool b ) +{ + m_pLinkedViewCheckBox->blockSignals( true ); + m_pLinkedViewCheckBox->setChecked( b ); + m_pLinkedViewCheckBox->blockSignals( false ); +} + +void KonqFrameStatusBar::updateActiveStatus() +{ + if ( !m_led->isShown() ) + { + unsetPalette(); + return; + } + + bool hasFocus = m_pParentKonqFrame->isActivePart(); + + const QColorGroup& activeCg = kapp->palette().active(); + setPaletteBackgroundColor( hasFocus ? activeCg.midlight() : activeCg.mid() ); + + static QPixmap indicator_viewactive( UserIcon( "indicator_viewactive" ) ); + static QPixmap indicator_empty( UserIcon( "indicator_empty" ) ); + m_led->setPixmap( hasFocus ? indicator_viewactive : indicator_empty ); +} + +//################################################################### + +void KonqFrameBase::printFrameInfo(const QString& spaces) +{ + kdDebug(1202) << spaces << "KonqFrameBase " << this << " printFrameInfo not implemented in derived class!" << endl; +} + +//################################################################### + +KonqFrame::KonqFrame( QWidget* parent, KonqFrameContainerBase *parentContainer, const char *name ) +:QWidget(parent,name) +{ + //kdDebug(1202) << "KonqFrame::KonqFrame()" << endl; + + m_pLayout = 0L; + m_pView = 0L; + + // the frame statusbar + m_pStatusBar = new KonqFrameStatusBar( this, "KonquerorFrameStatusBar"); + m_pStatusBar->setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed )); + connect(m_pStatusBar, SIGNAL(clicked()), this, SLOT(slotStatusBarClicked())); + connect( m_pStatusBar, SIGNAL( linkedViewClicked( bool ) ), this, SLOT( slotLinkedViewClicked( bool ) ) ); + m_separator = 0; + m_pParentContainer = parentContainer; +} + +KonqFrame::~KonqFrame() +{ + //kdDebug(1202) << "KonqFrame::~KonqFrame() " << this << endl; +} + +bool KonqFrame::isActivePart() +{ + return ( m_pView && + static_cast<KonqView*>(m_pView) == m_pView->mainWindow()->currentView() ); +} + +void KonqFrame::listViews( ChildViewList *viewList ) +{ + viewList->append( childView() ); +} + +void KonqFrame::saveConfig( KConfig* config, const QString &prefix, bool saveURLs, KonqFrameBase* docContainer, int /*id*/, int /*depth*/ ) +{ + if (saveURLs) + config->writePathEntry( QString::fromLatin1( "URL" ).prepend( prefix ), + childView()->url().url() ); + config->writeEntry( QString::fromLatin1( "ServiceType" ).prepend( prefix ), childView()->serviceType() ); + config->writeEntry( QString::fromLatin1( "ServiceName" ).prepend( prefix ), childView()->service()->desktopEntryName() ); + config->writeEntry( QString::fromLatin1( "PassiveMode" ).prepend( prefix ), childView()->isPassiveMode() ); + config->writeEntry( QString::fromLatin1( "LinkedView" ).prepend( prefix ), childView()->isLinkedView() ); + config->writeEntry( QString::fromLatin1( "ToggleView" ).prepend( prefix ), childView()->isToggleView() ); + config->writeEntry( QString::fromLatin1( "LockedLocation" ).prepend( prefix ), childView()->isLockedLocation() ); + //config->writeEntry( QString::fromLatin1( "ShowStatusBar" ).prepend( prefix ), statusbar()->isVisible() ); + if (this == docContainer) config->writeEntry( QString::fromLatin1( "docContainer" ).prepend( prefix ), true ); + + KonqConfigEvent ev( config, prefix+"_", true/*save*/); + QApplication::sendEvent( childView()->part(), &ev ); +} + +void KonqFrame::copyHistory( KonqFrameBase *other ) +{ + assert( other->frameType() == "View" ); + childView()->copyHistory( static_cast<KonqFrame *>( other )->childView() ); +} + +void KonqFrame::printFrameInfo( const QString& spaces ) +{ + QString className = "NoPart"; + if (part()) className = part()->widget()->className(); + kdDebug(1202) << spaces << "KonqFrame " << this << " visible=" << QString("%1").arg(isVisible()) << " containing view " + << childView() << " visible=" << QString("%1").arg(isVisible()) + << " and part " << part() << " whose widget is a " << className << endl; +} + +KParts::ReadOnlyPart *KonqFrame::attach( const KonqViewFactory &viewFactory ) +{ + KonqViewFactory factory( viewFactory ); + + // Note that we set the parent to 0. + // We don't want that deleting the widget deletes the part automatically + // because we already have that taken care of in KParts... + + m_pPart = factory.create( this, "view widget", 0, "" ); + + assert( m_pPart->widget() ); + + attachInternal(); + + m_pStatusBar->slotConnectToNewView(0, 0,m_pPart); + + return m_pPart; +} + +void KonqFrame::attachInternal() +{ + //kdDebug(1202) << "KonqFrame::attachInternal()" << endl; + delete m_pLayout; + + m_pLayout = new QVBoxLayout( this, 0, -1, "KonqFrame's QVBoxLayout" ); + + m_pLayout->addWidget( m_pPart->widget(), 1 ); + + m_pLayout->addWidget( m_pStatusBar, 0 ); + m_pPart->widget()->show(); + + m_pLayout->activate(); + + m_pPart->widget()->installEventFilter(this); +} + +bool KonqFrame::eventFilter(QObject* /*obj*/, QEvent *ev) +{ + if (ev->type()==QEvent::KeyPress) + { + QKeyEvent * keyEv = static_cast<QKeyEvent*>(ev); + if ((keyEv->key()==Key_Tab) && (keyEv->state()==ControlButton)) + { + emit ((KonqFrameContainer*)parent())->ctrlTabPressed(); + return true; + } + } + return false; +} + +void KonqFrame::insertTopWidget( QWidget * widget ) +{ + assert(m_pLayout); + m_pLayout->insertWidget( 0, widget ); + if (widget!=0) + widget->installEventFilter(this); +} + +void KonqFrame::setView( KonqView* child ) +{ + m_pView = child; + if (m_pView) + { + connect(m_pView,SIGNAL(sigPartChanged(KonqView *, KParts::ReadOnlyPart *,KParts::ReadOnlyPart *)), + m_pStatusBar,SLOT(slotConnectToNewView(KonqView *, KParts::ReadOnlyPart *,KParts::ReadOnlyPart *))); + } +} + +void KonqFrame::setTitle( const QString &title , QWidget* /*sender*/) +{ + //kdDebug(1202) << "KonqFrame::setTitle( " << title << " )" << endl; + m_title = title; + if (m_pParentContainer) m_pParentContainer->setTitle( title , this); +} + +void KonqFrame::setTabIcon( const KURL &url, QWidget* /*sender*/ ) +{ + //kdDebug(1202) << "KonqFrame::setTabIcon( " << url << " )" << endl; + if (m_pParentContainer) m_pParentContainer->setTabIcon( url, this ); +} + +void KonqFrame::reparentFrame( QWidget* parent, const QPoint & p, bool showIt ) +{ + QWidget::reparent( parent, p, showIt ); +} + +void KonqFrame::slotStatusBarClicked() +{ + if ( !isActivePart() && m_pView && !m_pView->isPassiveMode() ) + m_pView->mainWindow()->viewManager()->setActivePart( part() ); +} + +void KonqFrame::slotLinkedViewClicked( bool mode ) +{ + if ( m_pView->mainWindow()->linkableViewsCount() == 2 ) + m_pView->mainWindow()->slotLinkView(); + else + m_pView->setLinkedView( mode ); +} + +void +KonqFrame::paintEvent( QPaintEvent* ) +{ + m_pStatusBar->repaint(); +} + +void KonqFrame::slotRemoveView() +{ + m_pView->mainWindow()->viewManager()->removeView( m_pView ); +} + +void KonqFrame::activateChild() +{ + if (m_pView && !m_pView->isPassiveMode() ) + m_pView->mainWindow()->viewManager()->setActivePart( part() ); +} + +//################################################################### + +void KonqFrameContainerBase::printFrameInfo(const QString& spaces) +{ + kdDebug(1202) << spaces << "KonqFrameContainerBase " << this << ", this shouldn't happen!" << endl; +} + +//################################################################### + +KonqFrameContainer::KonqFrameContainer( Orientation o, + QWidget* parent, + KonqFrameContainerBase* parentContainer, + const char * name) + : QSplitter( o, parent, name ), m_bAboutToBeDeleted(false) +{ + m_pParentContainer = parentContainer; + m_pFirstChild = 0L; + m_pSecondChild = 0L; + m_pActiveChild = 0L; + setOpaqueResize( KGlobalSettings::opaqueResize() ); +} + +KonqFrameContainer::~KonqFrameContainer() +{ + //kdDebug(1202) << "KonqFrameContainer::~KonqFrameContainer() " << this << " - " << className() << endl; + delete m_pFirstChild; + delete m_pSecondChild; +} + +void KonqFrameContainer::listViews( ChildViewList *viewList ) +{ + if( m_pFirstChild ) + m_pFirstChild->listViews( viewList ); + + if( m_pSecondChild ) + m_pSecondChild->listViews( viewList ); +} + +void KonqFrameContainer::saveConfig( KConfig* config, const QString &prefix, bool saveURLs, KonqFrameBase* docContainer, int id, int depth ) +{ + int idSecond = id + (int)pow( 2.0, depth ); + + //write children sizes + config->writeEntry( QString::fromLatin1( "SplitterSizes" ).prepend( prefix ), sizes() ); + + //write children + QStringList strlst; + if( firstChild() ) + strlst.append( QString::fromLatin1( firstChild()->frameType() ) + QString::number(idSecond - 1) ); + if( secondChild() ) + strlst.append( QString::fromLatin1( secondChild()->frameType() ) + QString::number( idSecond ) ); + + config->writeEntry( QString::fromLatin1( "Children" ).prepend( prefix ), strlst ); + + //write orientation + QString o; + if( orientation() == Qt::Horizontal ) + o = QString::fromLatin1("Horizontal"); + else if( orientation() == Qt::Vertical ) + o = QString::fromLatin1("Vertical"); + config->writeEntry( QString::fromLatin1( "Orientation" ).prepend( prefix ), o ); + + //write docContainer + if (this == docContainer) config->writeEntry( QString::fromLatin1( "docContainer" ).prepend( prefix ), true ); + + if (m_pSecondChild == m_pActiveChild) config->writeEntry( QString::fromLatin1( "activeChildIndex" ).prepend( prefix ), 1 ); + else config->writeEntry( QString::fromLatin1( "activeChildIndex" ).prepend( prefix ), 0 ); + + //write child configs + if( firstChild() ) { + QString newPrefix = QString::fromLatin1( firstChild()->frameType() ) + QString::number(idSecond - 1); + newPrefix.append( '_' ); + firstChild()->saveConfig( config, newPrefix, saveURLs, docContainer, id, depth + 1 ); + } + + if( secondChild() ) { + QString newPrefix = QString::fromLatin1( secondChild()->frameType() ) + QString::number( idSecond ); + newPrefix.append( '_' ); + secondChild()->saveConfig( config, newPrefix, saveURLs, docContainer, idSecond, depth + 1 ); + } +} + +void KonqFrameContainer::copyHistory( KonqFrameBase *other ) +{ + assert( other->frameType() == "Container" ); + if ( firstChild() ) + firstChild()->copyHistory( static_cast<KonqFrameContainer *>( other )->firstChild() ); + if ( secondChild() ) + secondChild()->copyHistory( static_cast<KonqFrameContainer *>( other )->secondChild() ); +} + +KonqFrameBase* KonqFrameContainer::otherChild( KonqFrameBase* child ) +{ + if( firstChild() == child ) + return secondChild(); + else if( secondChild() == child ) + return firstChild(); + return 0L; +} + +void KonqFrameContainer::printFrameInfo( const QString& spaces ) +{ + kdDebug(1202) << spaces << "KonqFrameContainer " << this << " visible=" << QString("%1").arg(isVisible()) + << " activeChild=" << m_pActiveChild << endl; + if (!m_pActiveChild) + kdDebug(1202) << "WARNING: " << this << " has a null active child!" << endl; + KonqFrameBase* child = firstChild(); + if (child != 0L) + child->printFrameInfo(spaces + " "); + else + kdDebug(1202) << spaces << " Null child" << endl; + child = secondChild(); + if (child != 0L) + child->printFrameInfo(spaces + " "); + else + kdDebug(1202) << spaces << " Null child" << endl; +} + +void KonqFrameContainer::reparentFrame( QWidget* parent, const QPoint & p, bool showIt ) +{ + QWidget::reparent( parent, p, showIt ); +} + +void KonqFrameContainer::swapChildren() +{ + KonqFrameBase *firstCh = m_pFirstChild; + m_pFirstChild = m_pSecondChild; + m_pSecondChild = firstCh; +} + +void KonqFrameContainer::setTitle( const QString &title , QWidget* sender) +{ + //kdDebug(1202) << "KonqFrameContainer::setTitle( " << title << " , " << sender << " )" << endl; + if (m_pParentContainer && activeChild() && (sender == activeChild()->widget())) + m_pParentContainer->setTitle( title , this); +} + +void KonqFrameContainer::setTabIcon( const KURL &url, QWidget* sender ) +{ + //kdDebug(1202) << "KonqFrameContainer::setTabIcon( " << url << " , " << sender << " )" << endl; + if (m_pParentContainer && activeChild() && (sender == activeChild()->widget())) + m_pParentContainer->setTabIcon( url, this ); +} + +void KonqFrameContainer::insertChildFrame( KonqFrameBase* frame, int /*index*/ ) +{ + //kdDebug(1202) << "KonqFrameContainer " << this << ": insertChildFrame " << frame << endl; + + if (frame) + { + if( !m_pFirstChild ) + { + m_pFirstChild = frame; + frame->setParentContainer(this); + //kdDebug(1202) << "Setting as first child" << endl; + } + else if( !m_pSecondChild ) + { + m_pSecondChild = frame; + frame->setParentContainer(this); + //kdDebug(1202) << "Setting as second child" << endl; + } + else + kdWarning(1202) << this << " already has two children..." + << m_pFirstChild << " and " << m_pSecondChild << endl; + } else + kdWarning(1202) << "KonqFrameContainer " << this << ": insertChildFrame(0L) !" << endl; +} + +void KonqFrameContainer::removeChildFrame( KonqFrameBase * frame ) +{ + //kdDebug(1202) << "KonqFrameContainer::RemoveChildFrame " << this << ". Child " << frame << " removed" << endl; + + if( m_pFirstChild == frame ) + { + m_pFirstChild = m_pSecondChild; + m_pSecondChild = 0L; + } + else if( m_pSecondChild == frame ) + m_pSecondChild = 0L; + + else + kdWarning(1202) << this << " Can't find this child:" << frame << endl; +} + +void KonqFrameContainer::childEvent( QChildEvent *c ) +{ + // Child events cause layout changes. These are unnecassery if we are going + // to be deleted anyway. + if (!m_bAboutToBeDeleted) + QSplitter::childEvent(c); +} + +void KonqFrameContainer::setRubberband( int pos ) +{ + emit setRubberbandCalled(); + QSplitter::setRubberband( pos ); +} + +#include "konq_frame.moc" diff --git a/konqueror/konq_frame.h b/konqueror/konq_frame.h new file mode 100644 index 000000000..24ff77faa --- /dev/null +++ b/konqueror/konq_frame.h @@ -0,0 +1,410 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Michael Reiher <[email protected]> + + 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_frame_h__ +#define __konq_frame_h__ + +#include "konq_factory.h" + +#include <qguardedptr.h> +#include <qcolor.h> +#include <qwidget.h> +#include <qsplitter.h> +#include <qcheckbox.h> +#include <qlabel.h> + +#include <kpixmap.h> +#include <kpixmapeffect.h> +#include <kstatusbar.h> + +class QPixmap; +class QVBoxLayout; +class QHBoxLayout; +class QTimer; +class QPushButton; +class QToolButton; + +class KonqView; +class KonqViewManager; +class KonqFrameBase; +class KonqFrame; +class KonqFrameContainerBase; +class KonqFrameContainer; +class KonqFrameTabs; +class KConfig; +class KSeparator; +class KProgress; +class KAction; +class KSqueezedTextLabel; + +namespace KParts +{ + class ReadOnlyPart; +} + +/** + * A CheckBox with a special paintEvent(). It looks like the + * unchecked radiobutton in b2k style if unchecked and contains a little + * anchor if checked. + */ +class KonqCheckBox : public QCheckBox +{ + Q_OBJECT // for classname +public: + KonqCheckBox(QWidget *parent=0, const char *name=0) + :QCheckBox( parent, name ) {} +protected: + void drawButton( QPainter * ); +}; + + + +/** + * The KonqFrameStatusBar is the statusbar under each konqueror view. + * It indicates in particular whether a view is active or not. + */ +class KonqFrameStatusBar : public KStatusBar +{ + Q_OBJECT + + public: + KonqFrameStatusBar( KonqFrame *_parent = 0L, const char *_name = 0L ); + virtual ~KonqFrameStatusBar(); + + /** + * Checks/unchecks the linked-view checkbox + */ + void setLinkedView( bool b ); + /** + * Shows/hides the active-view indicator + */ + void showActiveViewIndicator( bool b ); + /** + * Shows/hides the linked-view indicator + */ + void showLinkedViewIndicator( bool b ); + /** + * Updates the active-view indicator and the statusbar color. + */ + void updateActiveStatus(); + + public slots: + void slotConnectToNewView(KonqView *, KParts::ReadOnlyPart *oldOne,KParts::ReadOnlyPart *newOne); + void slotLoadingProgress( int percent ); + void slotSpeedProgress( int bytesPerSecond ); + void slotDisplayStatusText(const QString& text); + + void slotClear(); + void message ( const QString & message ); + + signals: + /** + * This signal is emitted when the user clicked the bar. + */ + void clicked(); + + /** + * The "linked view" checkbox was clicked + */ + void linkedViewClicked( bool mode ); + + protected: + virtual bool eventFilter(QObject*,QEvent *); + virtual void resizeEvent( QResizeEvent* ); + virtual void mousePressEvent( QMouseEvent* ); + /** + * Brings up the context menu for this frame + */ + virtual void splitFrameMenu(); + + /** + * Takes care of the statusbars size + **/ + virtual void fontChange(const QFont &oldFont); + + private: + KonqFrame* m_pParentKonqFrame; + QCheckBox *m_pLinkedViewCheckBox; + KProgress *m_progressBar; + KSqueezedTextLabel *m_pStatusLabel; + QLabel* m_led; + QString m_savedMessage; +}; + + +typedef QPtrList<KonqView> ChildViewList; + +class KonqFrameBase +{ + public: + virtual ~KonqFrameBase() {} + + virtual void saveConfig( KConfig* config, const QString &prefix, bool saveURLs, KonqFrameBase* docContainer, int id = 0, int depth = 0) = 0; + + virtual void copyHistory( KonqFrameBase *other ) = 0; + + virtual void printFrameInfo( const QString& spaces ); + + virtual void reparentFrame( QWidget* parent, + const QPoint & p, bool showIt=FALSE ) = 0; + + virtual KonqFrameContainerBase* parentContainer() { return m_pParentContainer; } + virtual void setParentContainer(KonqFrameContainerBase* parent) { m_pParentContainer = parent; } + + virtual void setTitle( const QString &title , QWidget* sender) = 0; + virtual void setTabIcon( const KURL &url, QWidget* sender ) = 0; + + virtual QWidget* widget() = 0; + + virtual void listViews( ChildViewList *viewList ) = 0; + virtual QCString frameType() = 0; + + virtual void activateChild() = 0; + + virtual KonqView* activeChildView() = 0; + +protected: + KonqFrameBase() {} + + KonqFrameContainerBase* m_pParentContainer; +}; + +/** + * The KonqFrame is the actual container for the views. It takes care of the + * widget handling i.e. it attaches/detaches the view widget and activates + * them on click at the statusbar. + * + * KonqFrame makes the difference between built-in views and remote ones. + * We create a layout in it (with the KonqFrameStatusBar as top item in the layout) + * For builtin views we have the view as direct child widget of the layout + * For remote views we have an OPFrame, having the view attached, as child + * widget of the layout + */ + +class KonqFrame : public QWidget, public KonqFrameBase +{ + Q_OBJECT + +public: + KonqFrame( QWidget* parent, KonqFrameContainerBase *parentContainer = 0L, + const char *name = 0L ); + virtual ~KonqFrame(); + + /** + * Attach a view to the KonqFrame. + * @param viewFactory the view to attach (instead of the current one, if any) + */ + KParts::ReadOnlyPart *attach( const KonqViewFactory &viewFactory ); + + /** + * Filters the CTRL+Tab event from the views and emits ctrlTabPressed to + make KonqMainWindow switch to the next view + */ + virtual bool eventFilter(QObject*obj,QEvent *ev); + + /** + * Inserts the part's widget and the statusbar into the layout + */ + void attachInternal(); + + /** + * Inserts a widget at the top of the part's widget, in the layout + * (used for the find functionality) + */ + void insertTopWidget( QWidget * widget ); + + /** + * Returns the part that is currently connected to the Frame. + */ + KParts::ReadOnlyPart *part() { return m_pPart; } + /** + * Returns the view that is currently connected to the Frame. + */ + KonqView* childView()const { return m_pView; } + + bool isActivePart(); + + void setView( KonqView* child ); + virtual void listViews( ChildViewList *viewList ); + + virtual void saveConfig( KConfig* config, const QString &prefix, bool saveURLs, KonqFrameBase* docContainer, int id = 0, int depth = 0 ); + virtual void copyHistory( KonqFrameBase *other ); + + virtual void printFrameInfo( const QString& spaces ); + + virtual void setTitle( const QString &title, QWidget* sender ); + virtual void setTabIcon( const KURL &url, QWidget* sender ); + + virtual void reparentFrame(QWidget * parent, + const QPoint & p, bool showIt=FALSE ); + + //virtual KonqFrameContainerBase* parentContainer(); + virtual QWidget* widget() { return this; } + virtual QCString frameType() { return QCString("View"); } + + QVBoxLayout *layout()const { return m_pLayout; } + + KonqFrameStatusBar *statusbar() const { return m_pStatusBar; } + + virtual void activateChild(); + + KonqView* activeChildView() { return m_pView; } + + QString title() const { return m_title; } + +public slots: + + /** + * Is called when the frame statusbar has been clicked + */ + void slotStatusBarClicked(); + + void slotLinkedViewClicked( bool mode ); + + /** + * Is called when 'Remove View' is called from the popup menu + */ + void slotRemoveView(); + +protected: + virtual void paintEvent( QPaintEvent* ); + + QVBoxLayout *m_pLayout; + QGuardedPtr<KonqView> m_pView; + + QGuardedPtr<KParts::ReadOnlyPart> m_pPart; + + KonqViewManager* m_pViewManager; + + KSeparator *m_separator; + KonqFrameStatusBar* m_pStatusBar; + + QString m_title; +}; + +class KonqFrameContainerBase : public KonqFrameBase +{ +public: + virtual ~KonqFrameContainerBase() {} + + /** + * Call this after inserting a new frame into the splitter. + */ + virtual void insertChildFrame( KonqFrameBase * frame, int index = -1 ) = 0; + /** + * Call this before deleting one of our children. + */ + virtual void removeChildFrame( KonqFrameBase * frame ) = 0; + + //inherited + virtual void printFrameInfo( const QString& spaces ); + + virtual QCString frameType() { return QCString("ContainerBase"); } + + virtual void reparentFrame(QWidget * parent, + const QPoint & p, bool showIt=FALSE ) = 0; + + virtual KonqFrameBase* activeChild() { return m_pActiveChild; } + + virtual void setActiveChild( KonqFrameBase* activeChild ) { m_pActiveChild = activeChild; + m_pParentContainer->setActiveChild( this ); } + + virtual void activateChild() { if (m_pActiveChild) m_pActiveChild->activateChild(); } + + virtual KonqView* activeChildView() { if (m_pActiveChild) return m_pActiveChild->activeChildView(); + else return 0L; } + +protected: + KonqFrameContainerBase() {} + + KonqFrameBase* m_pActiveChild; +}; + +/** + * With KonqFrameContainers and @refKonqFrames we can create a flexible + * storage structure for the views. The top most element is a + * KonqFrameContainer. It's a direct child of the MainView. We can then + * build up a binary tree of containers. KonqFrameContainers are the nodes. + * That means that they always have two childs. Which are either again + * KonqFrameContainers or, as leaves, KonqFrames. + */ + +class KonqFrameContainer : public QSplitter, public KonqFrameContainerBase +{ + Q_OBJECT + friend class KonqFrame; //for emitting ctrlTabPressed() only, aleXXX +public: + KonqFrameContainer( Orientation o, + QWidget* parent, + KonqFrameContainerBase* parentContainer, + const char * name = 0); + virtual ~KonqFrameContainer(); + + virtual void listViews( ChildViewList *viewList ); + + virtual void saveConfig( KConfig* config, const QString &prefix, bool saveURLs, KonqFrameBase* docContainer, int id = 0, int depth = 0 ); + virtual void copyHistory( KonqFrameBase *other ); + + KonqFrameBase* firstChild() { return m_pFirstChild; } + KonqFrameBase* secondChild() { return m_pSecondChild; } + KonqFrameBase* otherChild( KonqFrameBase* child ); + + virtual void printFrameInfo( const QString& spaces ); + + void swapChildren(); + + virtual void setTitle( const QString &title, QWidget* sender ); + virtual void setTabIcon( const KURL &url, QWidget* sender ); + + virtual QWidget* widget() { return this; } + virtual QCString frameType() { return QCString("Container"); } + + /** + * Call this after inserting a new frame into the splitter. + */ + void insertChildFrame( KonqFrameBase * frame, int index = -1 ); + /** + * Call this before deleting one of our children. + */ + void removeChildFrame( KonqFrameBase * frame ); + + //inherited + virtual void reparentFrame(QWidget * parent, + const QPoint & p, bool showIt=FALSE ); + + //make this one public + int idAfter( QWidget* w ){ return QSplitter::idAfter( w ); } + + void setAboutToBeDeleted() { m_bAboutToBeDeleted = true; } + + //inherited + virtual void childEvent( QChildEvent * ); + +signals: + void ctrlTabPressed(); + void setRubberbandCalled(); + +protected: + virtual void setRubberband( int ); + + KonqFrameBase* m_pFirstChild; + KonqFrameBase* m_pSecondChild; + bool m_bAboutToBeDeleted; +}; + +#endif diff --git a/konqueror/konq_guiclients.cc b/konqueror/konq_guiclients.cc new file mode 100644 index 000000000..7a3dbaca8 --- /dev/null +++ b/konqueror/konq_guiclients.cc @@ -0,0 +1,358 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Simon Hausmann <[email protected]> + + 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 <kdebug.h> +#include <klocale.h> +#include <kmenubar.h> +#include "konq_view.h" +#include "konq_settingsxt.h" +#include "konq_frame.h" +#include "konq_guiclients.h" +#include "konq_viewmgr.h" +#include <kiconloader.h> + +PopupMenuGUIClient::PopupMenuGUIClient( KonqMainWindow *mainWindow, + const KTrader::OfferList &embeddingServices, + bool showEmbeddingServices, bool doTabHandling ) +{ + //giving a name to each guiclient: just for debugging + // (needs delete instance() in the dtor if enabled for good) + //setInstance( new KInstance( "PopupMenuGUIClient" ) ); + + m_mainWindow = mainWindow; + + m_doc = QDomDocument( "kpartgui" ); + QDomElement root = m_doc.createElement( "kpartgui" ); + root.setAttribute( "name", "konqueror" ); + m_doc.appendChild( root ); + + QDomElement menu = m_doc.createElement( "Menu" ); + root.appendChild( menu ); + menu.setAttribute( "name", "popupmenu" ); + + if ( !mainWindow->menuBar()->isVisible() ) + { + QDomElement showMenuBarElement = m_doc.createElement( "action" ); + showMenuBarElement.setAttribute( "name", "options_show_menubar" ); + menu.appendChild( showMenuBarElement ); + + menu.appendChild( m_doc.createElement( "separator" ) ); + } + + if ( mainWindow->fullScreenMode() ) + { + QDomElement stopFullScreenElement = m_doc.createElement( "action" ); + stopFullScreenElement.setAttribute( "name", "fullscreen" ); + menu.appendChild( stopFullScreenElement ); + + menu.appendChild( m_doc.createElement( "separator" ) ); + } + + if ( showEmbeddingServices ) + { + KTrader::OfferList::ConstIterator it = embeddingServices.begin(); + KTrader::OfferList::ConstIterator end = embeddingServices.end(); + + if ( embeddingServices.count() == 1 ) + { + KService::Ptr service = *embeddingServices.begin(); + addEmbeddingService( menu, 0, i18n( "Preview in %1" ).arg( service->name() ), service ); + } + else if ( embeddingServices.count() > 1 ) + { + int idx = 0; + QDomElement subMenu = m_doc.createElement( "menu" ); + menu.appendChild( subMenu ); + QDomElement text = m_doc.createElement( "text" ); + subMenu.appendChild( text ); + text.appendChild( m_doc.createTextNode( i18n( "Preview In" ) ) ); + subMenu.setAttribute( "group", "preview" ); + subMenu.setAttribute( "name", "preview submenu" ); + + bool inserted = false; + + for (; it != end; ++it, ++idx ) + { + addEmbeddingService( subMenu, idx, (*it)->name(), *it ); + inserted = true; + } + + if ( !inserted ) // oops, if empty then remove the menu :-] + menu.removeChild( menu.namedItem( "menu" ) ); + } + } + + if ( doTabHandling ) + { + QDomElement openInSameWindow = m_doc.createElement( "action" ); + openInSameWindow.setAttribute( "name", "sameview" ); + openInSameWindow.setAttribute( "group", "tabhandling" ); + menu.appendChild( openInSameWindow ); + + QDomElement openInWindow = m_doc.createElement( "action" ); + openInWindow.setAttribute( "name", "newview" ); + openInWindow.setAttribute( "group", "tabhandling" ); + menu.appendChild( openInWindow ); + + QDomElement openInTabElement = m_doc.createElement( "action" ); + openInTabElement.setAttribute( "name", "openintab" ); + openInTabElement.setAttribute( "group", "tabhandling" ); + menu.appendChild( openInTabElement ); + + QDomElement separatorElement = m_doc.createElement( "separator" ); + separatorElement.setAttribute( "group", "tabhandling" ); + menu.appendChild( separatorElement ); + } + + //kdDebug() << k_funcinfo << m_doc.toString() << endl; + + setDOMDocument( m_doc ); +} + +PopupMenuGUIClient::~PopupMenuGUIClient() +{ +} + +KAction *PopupMenuGUIClient::action( const QDomElement &element ) const +{ + KAction *res = KXMLGUIClient::action( element ); + + if ( !res ) + res = m_mainWindow->action( element ); + + return res; +} + +void PopupMenuGUIClient::addEmbeddingService( QDomElement &menu, int idx, const QString &name, const KService::Ptr &service ) +{ + QDomElement action = m_doc.createElement( "action" ); + menu.appendChild( action ); + + QCString actName; + actName.setNum( idx ); + + action.setAttribute( "name", QString::number( idx ) ); + + action.setAttribute( "group", "preview" ); + + (void)new KAction( name, service->pixmap( KIcon::Small ), 0, + m_mainWindow, SLOT( slotOpenEmbedded() ), actionCollection(), actName ); +} + +ToggleViewGUIClient::ToggleViewGUIClient( KonqMainWindow *mainWindow ) +: QObject( mainWindow ) +{ + m_mainWindow = mainWindow; + m_actions.setAutoDelete( true ); + + KTrader::OfferList offers = KTrader::self()->query( "Browser/View" ); + KTrader::OfferList::Iterator it = offers.begin(); + while ( it != offers.end() ) + { + QVariant prop = (*it)->property( "X-KDE-BrowserView-Toggable" ); + QVariant orientation = (*it)->property( "X-KDE-BrowserView-ToggableView-Orientation" ); + + if ( !prop.isValid() || !prop.toBool() || + !orientation.isValid() || orientation.toString().isEmpty() ) + { + offers.remove( it ); + it = offers.begin(); + } + else + ++it; + } + + m_empty = ( offers.count() == 0 ); + + if ( m_empty ) + return; + + KTrader::OfferList::ConstIterator cIt = offers.begin(); + KTrader::OfferList::ConstIterator cEnd = offers.end(); + for (; cIt != cEnd; ++cIt ) + { + QString description = i18n( "Show %1" ).arg( (*cIt)->name() ); + QString name = (*cIt)->desktopEntryName(); + //kdDebug(1202) << "ToggleViewGUIClient: name=" << name << endl; + KToggleAction *action = new KToggleAction( description, 0, mainWindow->actionCollection(), name.latin1() ); + action->setCheckedState( i18n( "Hide %1" ).arg( (*cIt)->name() ) ); + + // HACK + if ( (*cIt)->icon() != "unknown" ) + action->setIcon( (*cIt)->icon() ); + + connect( action, SIGNAL( toggled( bool ) ), + this, SLOT( slotToggleView( bool ) ) ); + + m_actions.insert( name, action ); + + QVariant orientation = (*cIt)->property( "X-KDE-BrowserView-ToggableView-Orientation" ); + bool horizontal = orientation.toString().lower() == "horizontal"; + m_mapOrientation.insert( name, horizontal ); + } + + connect( m_mainWindow, SIGNAL( viewAdded( KonqView * ) ), + this, SLOT( slotViewAdded( KonqView * ) ) ); + connect( m_mainWindow, SIGNAL( viewRemoved( KonqView * ) ), + this, SLOT( slotViewRemoved( KonqView * ) ) ); +} + +ToggleViewGUIClient::~ToggleViewGUIClient() +{ +} + +QPtrList<KAction> ToggleViewGUIClient::actions() const +{ + QPtrList<KAction> res; + + QDictIterator<KAction> it( m_actions ); + for (; it.current(); ++it ) + res.append( it.current() ); + + return res; +} + +void ToggleViewGUIClient::slotToggleView( bool toggle ) +{ + QString serviceName = QString::fromLatin1( sender()->name() ); + + bool horizontal = m_mapOrientation[ serviceName ]; + + KonqViewManager *viewManager = m_mainWindow->viewManager(); + + if ( toggle ) + { + + KonqView *childView = viewManager->splitWindow( horizontal ? Qt::Vertical : Qt::Horizontal, + QString::fromLatin1( "Browser/View" ), + serviceName, + !horizontal /* vertical = make it first */); + + QValueList<int> newSplitterSizes; + + if ( horizontal ) + newSplitterSizes << 100 << 30; + else + newSplitterSizes << 30 << 100; + + if (!childView || !childView->frame()) + return; + + // Toggleviews don't need their statusbar + childView->frame()->statusbar()->hide(); + + KonqFrameContainerBase *newContainer = childView->frame()->parentContainer(); + + if (newContainer->frameType()=="Container") + static_cast<KonqFrameContainer*>(newContainer)->setSizes( newSplitterSizes ); + +#if 0 // already done by splitWindow + if ( m_mainWindow->currentView() ) + { + QString locBarURL = m_mainWindow->currentView()->url().prettyURL(); // default one in case it doesn't set it + childView->openURL( m_mainWindow->currentView()->url(), locBarURL ); + } +#endif + + // If not passive, set as active :) + if (!childView->isPassiveMode()) + viewManager->setActivePart( childView->part() ); + + kdDebug() << "ToggleViewGUIClient::slotToggleView setToggleView(true) on " << childView << endl; + childView->setToggleView( true ); + + m_mainWindow->viewCountChanged(); + + } + else + { + QPtrList<KonqView> viewList; + + m_mainWindow->listViews( &viewList ); + + QPtrListIterator<KonqView> it( viewList ); + for (; it.current(); ++it ) + if ( it.current()->service()->desktopEntryName() == serviceName ) + // takes care of choosing the new active view, and also calls slotViewRemoved + viewManager->removeView( it.current() ); + } + +} + + +void ToggleViewGUIClient::saveConfig( bool add, const QString &serviceName ) +{ + // This is used on konqueror's startup....... so it's never used, since + // the K menu only contains calls to kfmclient...... + // Well, it could be useful again in the future. + // Currently, the profiles save this info. + QStringList toggableViewsShown = KonqSettings::toggableViewsShown(); + if (add) + { + if ( !toggableViewsShown.contains( serviceName ) ) + toggableViewsShown.append(serviceName); + } + else + toggableViewsShown.remove(serviceName); + KonqSettings::setToggableViewsShown( toggableViewsShown ); +} + +void ToggleViewGUIClient::slotViewAdded( KonqView *view ) +{ + QString name = view->service()->desktopEntryName(); + + KAction *action = m_actions[ name ]; + + if ( action ) + { + static_cast<KToggleAction *>( action )->setChecked( true ); + saveConfig( true, name ); + + // KonqView::isToggleView() is not set yet.. so just check for the orientation + +#if 0 + QVariant vert = view->service()->property( "X-KDE-BrowserView-ToggableView-Orientation"); + bool vertical = vert.toString().lower() == "vertical"; + QVariant nohead = view->service()->property( "X-KDE-BrowserView-ToggableView-NoHeader"); + bool noheader = nohead.isValid() ? nohead.toBool() : false; + // if it is a vertical toggle part, turn on the header. + // this works even when konq loads the view from a profile. + if ( vertical && (!noheader)) + { + view->frame()->header()->setText(view->service()->name()); + view->frame()->header()->setAction(action); + } +#endif + } +} + +void ToggleViewGUIClient::slotViewRemoved( KonqView *view ) +{ + QString name = view->service()->desktopEntryName(); + + KAction *action = m_actions[ name ]; + + if ( action ) + { + static_cast<KToggleAction *>( action )->setChecked( false ); + saveConfig( false, name ); + } +} + +#include "konq_guiclients.moc" diff --git a/konqueror/konq_guiclients.h b/konqueror/konq_guiclients.h new file mode 100644 index 000000000..3e34d3ee5 --- /dev/null +++ b/konqueror/konq_guiclients.h @@ -0,0 +1,97 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Simon Hausmann <[email protected]> + + 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 __konq_guiclients_h__ +#define __konq_guiclients_h__ + +#include <kxmlguiclient.h> +#include <qobject.h> +#include <qdict.h> +#include <ktrader.h> + +class KAction; +class KActionCollection; +class KonqMainWindow; +class KonqView; + +/** + * This XML-GUI-Client is passed to KonqPopupMenu to add extra actions into it, + * using the XMLGUI merging. It offers embedding actions and tabbed-browsing actions. + * Its XML looks like this: + * @code + + <kpartgui name="konqueror" > + <Menu name="popupmenu" > + <menu group="preview" name="preview submenu" > + <text>Preview In</text> + <action group="preview" name="0" /> + <action group="preview" name="1" /> + </menu> + <action group="tabhandling" name="sameview" /> + <action group="tabhandling" name="newview" /> + <action group="tabhandling" name="openintab" /> + <separator group="tabhandling" /> + </Menu> + </kpartgui> + + * @endcode + */ +class PopupMenuGUIClient : public KXMLGUIClient +{ +public: + PopupMenuGUIClient( KonqMainWindow *mainWindow, const KTrader::OfferList &embeddingServices, + bool isIntoTrash, bool doTabHandling ); + virtual ~PopupMenuGUIClient(); + + virtual KAction *action( const QDomElement &element ) const; + +private: + void addEmbeddingService( QDomElement &menu, int idx, const QString &name, const KService::Ptr &service ); + + KonqMainWindow *m_mainWindow; + + QDomDocument m_doc; +}; + +class ToggleViewGUIClient : public QObject +{ + Q_OBJECT +public: + ToggleViewGUIClient( KonqMainWindow *mainWindow ); + virtual ~ToggleViewGUIClient(); + + bool empty() const { return m_empty; } + + QPtrList<KAction> actions() const; + KAction *action( const QString &name ) { return m_actions[ name ]; } + + void saveConfig( bool add, const QString &serviceName ); + +private slots: + void slotToggleView( bool toggle ); + void slotViewAdded( KonqView *view ); + void slotViewRemoved( KonqView *view ); +private: + KonqMainWindow *m_mainWindow; + QDict<KAction> m_actions; + bool m_empty; + QMap<QString,bool> m_mapOrientation; +}; + +#endif diff --git a/konqueror/konq_main.cc b/konqueror/konq_main.cc new file mode 100644 index 000000000..e64016ed9 --- /dev/null +++ b/konqueror/konq_main.cc @@ -0,0 +1,222 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Simon Hausmann <[email protected]> + + 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_main.h" +#include "konq_misc.h" +#include "konq_factory.h" +#include "konq_mainwindow.h" +#include "konq_view.h" +#include "konq_settingsxt.h" +#include "KonquerorIface.h" + +#include <ktempfile.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <kcmdlineargs.h> +#include <dcopclient.h> +#include <kimageio.h> +#include <qfile.h> + +#include <qwidgetlist.h> + +static const KCmdLineOptions options[] = +{ + { "silent", I18N_NOOP("Start without a default window"), 0 }, + { "preload", I18N_NOOP("Preload for later use"), 0 }, + { "profile <profile>", I18N_NOOP("Profile to open"), 0 }, + { "profiles", I18N_NOOP("List available profiles"), 0 }, + { "mimetype <mimetype>", I18N_NOOP("Mimetype to use for this URL (e.g. text/html or inode/directory)"), 0 }, + { "select", I18N_NOOP("For URLs that point to files, opens the directory and selects the file, instead of opening the actual file"), 0 }, + { "+[URL]", I18N_NOOP("Location to open"), 0 }, + KCmdLineLastOption +}; + +extern "C" KDE_EXPORT int kdemain( int argc, char **argv ) +{ + KCmdLineArgs::init( argc, argv, KonqFactory::aboutData() ); + + KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. + KCmdLineArgs::addTempFileOption(); + + KonquerorApplication app; + + app.dcopClient()->registerAs( "konqueror" ); + + KonquerorIface *kiface = new KonquerorIface; + app.dcopClient()->setDefaultObject( kiface->objId() ); + + KGlobal::locale()->insertCatalogue("libkonq"); // needed for apps using libkonq + KImageIO::registerFormats(); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + KTempFile crashlog_file(locateLocal("tmp", "konqueror-crash-"), ".log"); + KonqMainWindow::s_crashlog_file = crashlog_file.file(); + + if ( kapp->isRestored() ) + { + int n = 1; + while ( KonqMainWindow::canBeRestored( n ) ) + { + QString className = KMainWindow::classNameOfToplevel( n ); + if( className == QString::fromLatin1( "KonqMainWindow" )) + (new KonqMainWindow( KURL(), false ) )->restore( n ); + else + kdWarning() << "Unknown class " << className << " in session saved data!" << endl; + n++; + } + } + else + { + if (args->isSet("profiles")) + { + QStringList profiles = KGlobal::dirs()->findAllResources("data", "konqueror/profiles/*", false, true); + profiles.sort(); + for(QStringList::ConstIterator it = profiles.begin(); + it != profiles.end(); ++it) + { + QString file = *it; + file = file.mid(file.findRev('/')+1); + printf("%s\n", QFile::encodeName(file).data()); + } + + return 0; + } + if (args->isSet("profile")) + { + QString profile = QString::fromLocal8Bit(args->getOption("profile")); + QString profilePath = profile; + if (profile[0] != '/') + profilePath = locate( "data", QString::fromLatin1("konqueror/profiles/")+profile ); + QString url; + QStringList filesToSelect; + if (args->count() == 1) + url = QString::fromLocal8Bit(args->arg(0)); + KURL kurl(url); + KParts::URLArgs urlargs; + if (args->isSet("mimetype")) + urlargs.serviceType = QString::fromLocal8Bit(args->getOption("mimetype")); + if (args->isSet("select")) { + QString fn = kurl.fileName(false); + if( !fn.isEmpty() ){ + filesToSelect += fn; + kurl.setFileName(""); + } + } + kdDebug(1202) << "main() -> createBrowserWindowFromProfile servicetype=" << urlargs.serviceType << endl; + KonqMisc::createBrowserWindowFromProfile( profilePath, profile, kurl, urlargs, false, filesToSelect ); + } + else + { + if (args->count() == 0) + { + if (args->isSet("preload")) + { + if( KonqSettings::maxPreloadCount() > 0 ) + { + DCOPRef ref( "kded", "konqy_preloader" ); + if( !ref.callExt( "registerPreloadedKonqy", DCOPRef::NoEventLoop, 5000, + app.dcopClient()->appId(), qt_xscreen())) + return 0; // too many preloaded or failed + KonqMainWindow* win = new KonqMainWindow( KURL(), false ); // prepare an empty window too + // KonqMainWindow ctor sets always the preloaded flag to false, so create the window before this + KonqMainWindow::setPreloadedFlag( true ); + KonqMainWindow::setPreloadedWindow( win ); + kdDebug(1202) << "Konqy preloaded :" << app.dcopClient()->appId() << endl; + } + else + { + return 0; // no preloading + } + } + else if (!args->isSet("silent")) + { + // By default try to open in webbrowser mode. People can use "konqueror ." to get a filemanager. + QString profile = "webbrowsing"; + QString profilePath = locate( "data", QString::fromLatin1("konqueror/profiles/")+profile ); + if ( !profilePath.isEmpty() ) { + KonqMisc::createBrowserWindowFromProfile( profilePath, profile ); + } else { + KonqMainWindow *mainWindow = new KonqMainWindow; + mainWindow->show(); + } + } + kdDebug(1202) << "main() -> no args" << endl; + } + else + { + KURL::List urlList; + KonqMainWindow * mainwin = 0L; + for ( int i = 0; i < args->count(); i++ ) + { + // KonqMisc::konqFilteredURL doesn't cope with local files... A bit of hackery below + KURL url = args->url(i); + KURL urlToOpen; + QStringList filesToSelect; + + if (url.isLocalFile() && QFile::exists(url.path())) // "konqueror index.html" + urlToOpen = url; + else + urlToOpen = KURL( KonqMisc::konqFilteredURL(0L, QString::fromLocal8Bit(args->arg(i))) ); // "konqueror slashdot.org" + + if ( !mainwin ) { + KParts::URLArgs urlargs; + if (args->isSet("mimetype")) + { + urlargs.serviceType = QString::fromLocal8Bit(args->getOption("mimetype")); + kdDebug(1202) << "main() : setting serviceType to " << urlargs.serviceType << endl; + } + if (args->isSet("select")) + { + QString fn = urlToOpen.fileName(false); + if( !fn.isEmpty() ){ + filesToSelect += fn; + urlToOpen.setFileName(""); + } + } + const bool tempFile = KCmdLineArgs::isTempFileSet(); + mainwin = KonqMisc::createNewWindow( urlToOpen, urlargs, false, filesToSelect, tempFile ); + } else + urlList += urlToOpen; + } + if ( mainwin ) + mainwin->openMultiURL( urlList ); + } + } + } + args->clear(); + + app.exec(); + + // Delete all KonqMainWindows, so that we don't have + // any parts loaded when KLibLoader::cleanUp is called. + // Their deletion was postponed in their event() + // (and Qt doesn't delete WDestructiveClose widgets on exit anyway :( ) + while( KonqMainWindow::mainWindowList() != NULL ) + { // the list will be deleted by last KonqMainWindow + delete KonqMainWindow::mainWindowList()->first(); + } + + delete kiface; + + crashlog_file.unlink(); + + return 0; +} diff --git a/konqueror/konq_main.h b/konqueror/konq_main.h new file mode 100644 index 000000000..ff72a5181 --- /dev/null +++ b/konqueror/konq_main.h @@ -0,0 +1,27 @@ +#ifndef __konq_main_h +#define __konq_main_h + +#include <kapplication.h> + +// This is used to know if we are being closed by session management +// or by the user. See KonqMainWindow::~KonqMainWindow. +// Credits to Matthias Ettrich for the idea. +class KonquerorApplication : public KApplication +{ +public: + KonquerorApplication() : KApplication(), + closed_by_sm( false ) {} + + bool closedByUser() const { return !closed_by_sm; } + void commitData(QSessionManager& sm) { + closed_by_sm = true; + KApplication::commitData( sm ); + closed_by_sm = false; + } + +private: + bool closed_by_sm; + +}; + +#endif diff --git a/konqueror/konq_mainwindow.cc b/konqueror/konq_mainwindow.cc new file mode 100644 index 000000000..071c7e0be --- /dev/null +++ b/konqueror/konq_mainwindow.cc @@ -0,0 +1,5907 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Simon Hausmann <[email protected]> + Copyright (C) 2000 Carsten Pfeiffer <[email protected]> + Copyright (C) 2000-2005 David Faure <[email protected]> + + 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_mainwindow.h" +#include "konq_guiclients.h" +#include "KonqMainWindowIface.h" +#include "konq_view.h" +#include "konq_run.h" +#include "konq_misc.h" +#include "konq_viewmgr.h" +#include "konq_frame.h" +#include "konq_tabs.h" +#include "konq_events.h" +#include "konq_actions.h" +#include "konq_settingsxt.h" +#include "konq_extensionmanager.h" +#include "delayedinitializer.h" +#include <konq_pixmapprovider.h> +#include <konq_operations.h> +#include <konqbookmarkmanager.h> +#include <kinputdialog.h> +#include <kzip.h> +#include <config.h> +#include <pwd.h> +// we define STRICT_ANSI to get rid of some warnings in glibc +#ifndef __STRICT_ANSI__ +#define __STRICT_ANSI__ +#define _WE_DEFINED_IT_ +#endif +#include <netdb.h> +#ifdef _WE_DEFINED_IT_ +#undef __STRICT_ANSI__ +#undef _WE_DEFINED_IT_ +#endif +#include <assert.h> +#include <stdlib.h> +#include <time.h> +#include <klargefile.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> + +#include <qfile.h> +#include <qclipboard.h> +#include <qmetaobject.h> +#include <qvbox.h> +#include <qlayout.h> +#include <qfileinfo.h> +#include <qwhatsthis.h> + +#include <dcopclient.h> +#include <kaboutdata.h> +#include <kbookmarkbar.h> +#include <kbookmarkmenu.h> +#include <kcmultidialog.h> +#include <kdebug.h> +#include <kedittoolbar.h> +#include <kkeydialog.h> +#include <kmenubar.h> +#include <kmessagebox.h> +#include <knewmenu.h> +#include <konq_defaults.h> +#include <konq_dirpart.h> +#include <konq_popupmenu.h> +#include <konq_settings.h> +#include "konq_main.h" +#include <konq_undo.h> +#include <kprotocolinfo.h> +#include <kstdaccel.h> +#include <kstdaction.h> +#include <kstandarddirs.h> +#include <ksycoca.h> +#include <ktempfile.h> +#include <kurlrequesterdlg.h> +#include <kurlrequester.h> +#include <kuserprofile.h> +#include <kwin.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kpopupmenu.h> +#include <kprocess.h> +#include <kio/scheduler.h> +#include <kio/netaccess.h> +#include <kaccelmanager.h> +#include <kuser.h> +#include <netwm.h> + +#ifdef KDE_MALLINFO_STDLIB +#include <stdlib.h> +#endif +#ifdef KDE_MALLINFO_MALLOC +#include <malloc.h> +#endif + +#include <X11/Xlib.h> +#include <sys/time.h> +#include <X11/Xatom.h> +#include <fixx11h.h> + +template class QPtrList<QPixmap>; +template class QPtrList<KToggleAction>; + +QPtrList<KonqMainWindow> *KonqMainWindow::s_lstViews = 0; +KConfig * KonqMainWindow::s_comboConfig = 0; +KCompletion * KonqMainWindow::s_pCompletion = 0; +QFile * KonqMainWindow::s_crashlog_file = 0; +bool KonqMainWindow::s_preloaded = false; +KonqMainWindow* KonqMainWindow::s_preloadedWindow = 0; +int KonqMainWindow::s_initialMemoryUsage = -1; +time_t KonqMainWindow::s_startupTime; +int KonqMainWindow::s_preloadUsageCount; + +KonqOpenURLRequest KonqOpenURLRequest::null; + +static int current_memory_usage( int* limit = NULL ); + +#include "konq_mainwindow_p.h" + +KonqExtendedBookmarkOwner::KonqExtendedBookmarkOwner(KonqMainWindow *w) +{ + m_pKonqMainWindow = w; +} + +KonqMainWindow::KonqMainWindow( const KURL &initialURL, bool openInitialURL, const char *name, const QString& xmluiFile) + : KParts::MainWindow( NoDCOPObject, 0L, name, WDestructiveClose | WStyle_ContextHelp | Qt::WGroupLeader ) +{ + setPreloadedFlag( false ); + + if ( !s_lstViews ) + s_lstViews = new QPtrList<KonqMainWindow>; + + s_lstViews->append( this ); + + m_urlCompletionStarted = false; + + m_currentView = 0L; + m_pChildFrame = 0L; + m_pActiveChild = 0L; + m_pWorkingTab = 0L; + m_initialKonqRun = 0L; + m_pBookmarkMenu = 0L; + m_dcopObject = new KonqMainWindowIface( this ); + m_combo = 0L; + m_bURLEnterLock = false; + m_bLocationBarConnected = false; + m_paBookmarkBar = 0L; + m_pURLCompletion = 0L; + m_goBuffer = 0; + m_configureDialog = 0L; + + m_bViewModeToggled = false; + + m_prevMenuBarVisible = true; + + m_pViewManager = new KonqViewManager( this ); + + m_toggleViewGUIClient = new ToggleViewGUIClient( this ); + + m_openWithActions.setAutoDelete( true ); + m_viewModeActions.setAutoDelete( true ); + m_toolBarViewModeActions.setAutoDelete( true ); + m_viewModeMenu = 0; + m_paCopyFiles = 0; + m_paMoveFiles = 0; + m_paDelete = 0; + m_paNewDir = 0; + m_bookmarkBarActionCollection = 0L; + KonqExtendedBookmarkOwner *extOwner = new KonqExtendedBookmarkOwner( this ); + m_pBookmarksOwner = extOwner; + connect( extOwner, + SIGNAL( signalFillBookmarksList(KExtendedBookmarkOwner::QStringPairList &) ), + extOwner, + SLOT( slotFillBookmarksList(KExtendedBookmarkOwner::QStringPairList &) ) ); + + // init history-manager, load history, get completion object + if ( !s_pCompletion ) { + KonqHistoryManager *mgr = new KonqHistoryManager( kapp, "history mgr" ); + s_pCompletion = mgr->completionObject(); + + + // setup the completion object before createGUI(), so that the combo + // picks up the correct mode from the HistoryManager (in slotComboPlugged) + int mode = KonqSettings::settingsCompletionMode(); + s_pCompletion->setCompletionMode( (KGlobalSettings::Completion) mode ); + } + connect(KParts::HistoryProvider::self(), SIGNAL(cleared()), SLOT(slotClearComboHistory())); + + KonqPixmapProvider *prov = KonqPixmapProvider::self(); + if ( !s_comboConfig ) { + s_comboConfig = new KConfig( "konq_history", false, false ); + KonqCombo::setConfig( s_comboConfig ); + s_comboConfig->setGroup( "Location Bar" ); + prov->load( s_comboConfig, "ComboIconCache" ); + } + connect( prov, SIGNAL( changed() ), SLOT( slotIconsChanged() ) ); + + initCombo(); + initActions(); + + setInstance( KGlobal::instance() ); + + connect( KSycoca::self(), SIGNAL( databaseChanged() ), + this, SLOT( slotDatabaseChanged() ) ); + + connect( kapp, SIGNAL( kdisplayFontChanged()), SLOT(slotReconfigure())); + + //load the xmlui file specified in the profile or the default konqueror.rc + setXMLFile( xmluiFile ); + + setStandardToolBarMenuEnabled( true ); + + createGUI( 0L ); + + connect(toolBarMenuAction(),SIGNAL(activated()),this,SLOT(slotForceSaveMainWindowSettings()) ); + + if ( !m_toggleViewGUIClient->empty() ) + plugActionList( QString::fromLatin1( "toggleview" ), m_toggleViewGUIClient->actions() ); + else + { + delete m_toggleViewGUIClient; + m_toggleViewGUIClient = 0; + } + + // Those menus are created by konqueror.rc so their address will never change + QPopupMenu *popup = static_cast<QPopupMenu*>(factory()->container("edit",this)); + if (popup) + KAcceleratorManager::manage(popup); + popup = static_cast<QPopupMenu*>(factory()->container("tools",this)); + if (popup) + KAcceleratorManager::manage(popup); + + m_bSaveViewPropertiesLocally = KonqSettings::saveViewPropertiesLocally(); + m_bHTMLAllowed = KonqSettings::htmlAllowed(); + + m_ptaUseHTML->setChecked( m_bHTMLAllowed ); + m_paSaveViewPropertiesLocally->setChecked( m_bSaveViewPropertiesLocally ); + + KonqUndoManager::incRef(); + + connect( KonqUndoManager::self(), SIGNAL( undoAvailable( bool ) ), + this, SLOT( slotUndoAvailable( bool ) ) ); + m_bNeedApplyKonqMainWindowSettings = true; + + if ( !initialURL.isEmpty() ) + { + openFilteredURL( initialURL.url() ); + } + else if ( openInitialURL ) + { + KURL homeURL; + homeURL.setPath( QDir::homeDirPath() ); + openURL( 0L, homeURL ); + } + else + // silent + m_bNeedApplyKonqMainWindowSettings = false; + + // Read basic main-view settings, and set to autosave + setAutoSaveSettings( "KonqMainWindow", false ); + + if ( !initialGeometrySet() ) + resize( 700, 480 ); + //kdDebug(1202) << "KonqMainWindow::KonqMainWindow " << this << " done" << endl; + + if( s_initialMemoryUsage == -1 ) + { + s_initialMemoryUsage = current_memory_usage(); + s_startupTime = time( NULL ); + s_preloadUsageCount = 0; + } +} + +KonqMainWindow::~KonqMainWindow() +{ + kdDebug(1202) << "KonqMainWindow::~KonqMainWindow " << this << endl; + + delete m_pViewManager; + + if ( s_lstViews ) + { + s_lstViews->removeRef( this ); + if ( s_lstViews->count() == 0 ) + { + delete s_lstViews; + s_lstViews = 0; + } + } + + disconnectActionCollection( actionCollection() ); + + saveToolBarServicesMap(); + + // createShellGUI( false ); + + delete m_pBookmarkMenu; + delete m_paBookmarkBar; + delete m_pBookmarksOwner; + delete m_pURLCompletion; + + m_viewModeActions.clear(); + + KonqUndoManager::decRef(); + + if ( s_lstViews == 0 ) { + delete KonqPixmapProvider::self(); + delete s_comboConfig; + s_comboConfig = 0L; + } + + delete m_configureDialog; + m_configureDialog = 0L; + delete m_dcopObject; + m_dcopObject = 0L; + delete m_combo; + m_combo = 0L; + delete m_locationLabel; + m_locationLabel = 0L; + + kdDebug(1202) << "KonqMainWindow::~KonqMainWindow " << this << " done" << endl; +} + +QWidget * KonqMainWindow::createContainer( QWidget *parent, int index, const QDomElement &element, int &id ) +{ + static QString nameBookmarkBar = QString::fromLatin1( "bookmarkToolBar" ); + static QString tagToolBar = QString::fromLatin1( "ToolBar" ); + + QWidget *res = KParts::MainWindow::createContainer( parent, index, element, id ); + + if ( res && (element.tagName() == tagToolBar) && (element.attribute( "name" ) == nameBookmarkBar) ) + { + assert( res->inherits( "KToolBar" ) ); + if (!kapp->authorizeKAction("bookmarks")) + { + delete res; + return 0; + } + + if ( !m_bookmarkBarActionCollection ) + { + // The actual menu needs a different action collection, so that the bookmarks + // don't appear in kedittoolbar + m_bookmarkBarActionCollection = new KActionCollection( this ); + m_bookmarkBarActionCollection->setHighlightingEnabled( true ); + connectActionCollection( m_bookmarkBarActionCollection ); + DelayedInitializer *initializer = new DelayedInitializer( QEvent::Show, res ); + connect( initializer, SIGNAL( initialize() ), this, SLOT(initBookmarkBar()) ); + } + } + + return res; +} + +void KonqMainWindow::initBookmarkBar() +{ + KToolBar * bar = static_cast<KToolBar *>( child( "bookmarkToolBar", "KToolBar" ) ); + + if (!bar) return; + + delete m_paBookmarkBar; + m_paBookmarkBar = new KBookmarkBar( KonqBookmarkManager::self(), m_pBookmarksOwner, bar, m_bookmarkBarActionCollection, this ); + connect( m_paBookmarkBar, + SIGNAL( aboutToShowContextMenu(const KBookmark &, QPopupMenu*) ), + this, SLOT( slotFillContextMenu(const KBookmark &, QPopupMenu*) )); + connect( m_paBookmarkBar, + SIGNAL( openBookmark(const QString &, Qt::ButtonState) ), + this, SLOT( slotOpenBookmarkURL(const QString &, Qt::ButtonState) )); + + // hide if empty + if (bar->count() == 0 ) + bar->hide(); +} + +void KonqMainWindow::removeContainer( QWidget *container, QWidget *parent, QDomElement &element, int id ) +{ + static QString nameBookmarkBar = QString::fromLatin1( "bookmarkToolBar" ); + static QString tagToolBar = QString::fromLatin1( "ToolBar" ); + + if ( element.tagName() == tagToolBar && element.attribute( "name" ) == nameBookmarkBar ) + { + assert( container->inherits( "KToolBar" ) ); + if (m_paBookmarkBar) + m_paBookmarkBar->clear(); + } + + KParts::MainWindow::removeContainer( container, parent, element, id ); +} + +// Detect a name filter (e.g. *.txt) in the url. +// Note that KShortURIFilter does the same, but we have no way of getting it from there +// +// Note: this removes the filter from the URL. +static QString detectNameFilter( KURL & url ) +{ + if ( !KProtocolInfo::supportsListing(url) ) + return QString::null; + + // Look for wildcard selection + QString nameFilter; + QString path = url.path(); + int lastSlash = path.findRev( '/' ); + if ( lastSlash > -1 ) + { + if ( !url.query().isEmpty() && lastSlash == (int)path.length()-1 ) { // In /tmp/?foo, foo isn't a query + path += url.query(); // includes the '?' + url.setQuery( QString::null ); + } + const QString fileName = path.mid( lastSlash + 1 ); + if ( fileName.find( '*' ) != -1 || fileName.find( '[' ) != -1 || fileName.find( '?' ) != -1 ) + { + // Check that a file or dir with all the special chars in the filename doesn't exist + if ( url.isLocalFile() ? !QFile::exists( path ) : !KIO::NetAccess::exists( url, false, 0 ) ) + { + nameFilter = fileName; + url.setFileName( QString::null ); + kdDebug(1202) << "Found wildcard. nameFilter=" << nameFilter << " New url=" << url << endl; + } + } + } + + return nameFilter; +} + +void KonqMainWindow::openFilteredURL( const QString & url, KonqOpenURLRequest & req ) +{ + // Filter URL to build a correct one + if (m_currentDir.isEmpty() && m_currentView) + m_currentDir = m_currentView->url().path(1); + + KURL filteredURL ( KonqMisc::konqFilteredURL( this, url, m_currentDir ) ); + kdDebug(1202) << "url " << url << " filtered into " << filteredURL.prettyURL() << endl; + + if ( filteredURL.isEmpty() ) // initially empty, or error (e.g. ~unknown_user) + return; + + m_currentDir = QString::null; + + openURL( 0L, filteredURL, QString::null, req ); + + // #4070: Give focus to view after URL was entered manually + // Note: we do it here if the view mode (i.e. part) wasn't changed + // If it is changed, then it's done in KonqView::changeViewMode + if ( m_currentView && m_currentView->part() ) + m_currentView->part()->widget()->setFocus(); + +} + +void KonqMainWindow::openFilteredURL( const QString & _url, bool inNewTab, bool tempFile ) +{ + KonqOpenURLRequest req( _url ); + req.newTab = inNewTab; + req.newTabInFront = true; + req.tempFile = tempFile; + + openFilteredURL( _url, req ); +} + +void KonqMainWindow::openURL( KonqView *_view, const KURL &_url, + const QString &_serviceType, KonqOpenURLRequest& req, + bool trustedSource ) +{ +#ifndef NDEBUG // needed for req.debug() + kdDebug(1202) << "KonqMainWindow::openURL : url = '" << _url << "' " + << "serviceType='" << _serviceType << "' req=" << req.debug() + << " view=" << _view << endl; +#endif + + KURL url( _url ); + QString serviceType( _serviceType ); + if ( url.url() == "about:blank" ) + { + serviceType = "text/html"; + } + else if ( !url.isValid() ) + { + KMessageBox::error(0, i18n("Malformed URL\n%1").arg(url.url())); + return; + } + else if ( !KProtocolInfo::isKnownProtocol( url ) && url.protocol() != "about" ) + { + KMessageBox::error(0, i18n("Protocol not supported\n%1").arg(url.protocol())); + return; + } + + QString nameFilter = detectNameFilter( url ); + if ( !nameFilter.isEmpty() ) + { + req.nameFilter = nameFilter; + url.setFileName( QString::null ); + } + + KonqView *view = _view; + + // When clicking a 'follow active' view (e.g. view is the sidebar), + // open the URL in the active view + if ( view && view->isFollowActive() ) + view = m_currentView; + + if ( !view && !req.newTab ) + view = m_currentView; /* Note, this can be 0L, e.g. on startup */ + else if ( !view && req.newTab ) { + view = m_pViewManager->addTab(QString::null, + QString::null, + false, + req.openAfterCurrentPage); + if (view) { + view->setCaption( _url.host() ); + view->setLocationBarURL( _url ); + if ( !req.args.frameName.isEmpty() ) + view->setViewName( req.args.frameName ); // #44961 + + if ( req.newTabInFront ) + m_pViewManager->showTab( view ); + + updateViewActions(); //A new tab created -- we may need to enable the "remove tab" button (#56318) + } + else + req.newTab = false; + } + + const QString oldLocationBarURL = m_combo->currentText(); + if ( view ) + { + if ( view == m_currentView ) + { + //will do all the stuff below plus GUI stuff + abortLoading(); + } + else + { + view->stop(); + // Don't change location bar if not current view + } + } + + // Fast mode for local files: do the stat ourselves instead of letting KRun do it. + if ( serviceType.isEmpty() && url.isLocalFile() ) + { + QCString _path( QFile::encodeName(url.path())); + KDE_struct_stat buff; + if ( KDE_stat( _path.data(), &buff ) != -1 ) + serviceType = KMimeType::findByURL( url, buff.st_mode )->name(); + } + + kdDebug(1202) << "trying openView for " << url << " (serviceType " << serviceType << ")" << endl; + if ( ( !serviceType.isEmpty() && serviceType != "application/octet-stream") || + url.url() == "about:konqueror" || url.url() == "about:plugins" ) + { + KService::Ptr offer = KServiceTypeProfile::preferredService(serviceType, "Application"); + // If the associated app is konqueror itself, then make sure we try to embed before bailing out. + if ( isMimeTypeAssociatedWithSelf( serviceType, offer ) ) + req.forceAutoEmbed = true; + + // Built-in view ? + if ( !openView( serviceType, url, view /* can be 0L */, req ) ) + { + //kdDebug(1202) << "KonqMainWindow::openURL : openView returned false" << endl; + // Are we following another view ? Then forget about this URL. Otherwise fire app. + if ( !req.followMode ) + { + //kdDebug(1202) << "KonqMainWindow::openURL : we were not following. Fire app." << endl; + // We know the servicetype, let's try its preferred service + if ( isMimeTypeAssociatedWithSelf( serviceType, offer ) ) { + KMessageBox::error( this, i18n("There appears to be a configuration error. You have associated Konqueror with %1, but it cannot handle this file type.").arg(serviceType)); + return; + } + if ( !url.isLocalFile() && KonqRun::isTextExecutable( serviceType ) ) + serviceType = "text/plain"; // view, don't execute + // Remote URL: save or open ? + QString protClass = KProtocolInfo::protocolClass(url.protocol()); + bool open = url.isLocalFile() || protClass==":local"; + if ( !open ) { + KParts::BrowserRun::AskSaveResult res = KonqRun::askSave( url, offer, serviceType ); + if ( res == KParts::BrowserRun::Save ) + KParts::BrowserRun::simpleSave( url, QString::null, this ); + open = ( res == KParts::BrowserRun::Open ); + } + if ( open ) + { + KURL::List lst; + lst.append(url); + //kdDebug(1202) << "Got offer " << (offer ? offer->name().latin1() : "0") << endl; + if ( ( trustedSource || KonqRun::allowExecution( serviceType, url ) ) && + ( KonqRun::isExecutable( serviceType ) || !offer || !KRun::run( *offer, lst ) ) ) + { + setLocationBarURL( oldLocationBarURL ); // Revert to previous locationbar URL + (void)new KRun( url, this ); + } + } + } + } + } + else // no known serviceType, use KonqRun + { + if ( ( !view || view->url().isEmpty() ) && !req.newTab ) // startup with argument + { + // Show it for now in the location bar, but we'll need to store it in the view + // later on (can't do it yet since either view == 0 or updateHistoryEntry will be called). + kdDebug(1202) << "setLocationBarURL (startup) : url = " << url << endl; + setLocationBarURL( url ); + } + + kdDebug(1202) << "Creating new konqrun for " << url << " req.typedURL=" << req.typedURL << endl; + + KonqRun * run = new KonqRun( this, view /* can be 0L */, url, req, trustedSource ); + + // Never start in external browser + run->setEnableExternalBrowser(false); + + if ( view ) + view->setRun( run ); + else if ( !req.newTab ) + { + // there can be only one :) (when not a new tab) + delete m_initialKonqRun; + m_initialKonqRun = run; + } + + if ( view == m_currentView ) + startAnimation(); + + connect( run, SIGNAL( finished() ), this, SLOT( slotRunFinished() ) ); + } +} + +bool KonqMainWindow::openView( QString serviceType, const KURL &_url, KonqView *childView, KonqOpenURLRequest& req ) +{ + // Second argument is referring URL + if ( !kapp->authorizeURLAction("open", childView ? childView->url() : KURL(), _url) ) + { + QString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, _url.prettyURL()); + KMessageBox::queuedMessageBox( this, KMessageBox::Error, msg ); + return true; // Nothing else to do. + } + + if ( KonqRun::isExecutable( serviceType ) ) + return false; // execute, don't open + // Contract: the caller of this method should ensure the view is stopped first. + +#ifndef NDEBUG + kdDebug(1202) << "KonqMainWindow::openView " << serviceType << " " << _url << " " << childView << " req:" << req.debug() << endl; +#endif + bool bOthersFollowed = false; + + if ( childView ) + { + // If we're not already following another view (and if we are not reloading) + if ( !req.followMode && !req.args.reload && !m_pViewManager->isLoadingProfile() ) + { + // When clicking a 'follow active' view (e.g. childView is the sidebar), + // open the URL in the active view + // (it won't do anything itself, since it's locked to its location) + if ( childView->isFollowActive() && childView != m_currentView ) + { + abortLoading(); + setLocationBarURL( _url ); + KonqOpenURLRequest newreq; + newreq.followMode = true; + newreq.args = req.args; + bOthersFollowed = openView( serviceType, _url, m_currentView, newreq ); + } + // "link views" feature, and "sidebar follows active view" feature + bOthersFollowed = makeViewsFollow(_url, req.args, serviceType, childView) || bOthersFollowed; + } + if ( childView->isLockedLocation() && !req.args.reload /* allow to reload a locked view*/ ) + return bOthersFollowed; + } + + QString indexFile; + + KURL url( _url ); + + // Generic mechanism for redirecting to tar:/<path>/ when clicking on a tar file, + // zip:/<path>/ when clicking on a zip file, etc. + // The name of the protocol to redirect to, is read from the mimetype's .desktop file + if ( url.isLocalFile() ) + { + KServiceType::Ptr ptr = KServiceType::serviceType( serviceType ); + if ( ptr ) + { + const QString protocol = ptr->property("X-KDE-LocalProtocol").toString(); + if ( !protocol.isEmpty() && KonqFMSettings::settings()->shouldEmbed( serviceType ) ) + { + url.setProtocol( protocol ); + if ( serviceType == "application/x-webarchive" ) + { + url.setPath( url.path() + "/index.html" ); + serviceType = "text/html"; + } + else + { + url.setPath( url.path() + '/' ); + serviceType = "inode/directory"; + } + } + } + } + + /////////// + + // In case we open an index.html, we want the location bar + // to still display the original URL (so that 'up' uses that URL, + // and since that's what the user entered). + // changeViewMode will take care of setting and storing that url. + QString originalURL = url.pathOrURL(); + if ( !req.nameFilter.isEmpty() ) // keep filter in location bar + { + if (!originalURL.endsWith("/")) + originalURL += '/'; + originalURL += req.nameFilter; + } + + QString serviceName; // default: none provided + + if ( url.url() == "about:konqueror" || url.url() == "about:plugins" ) + { + serviceType = "KonqAboutPage"; // not KParts/ReadOnlyPart, it fills the Location menu ! :) + serviceName = "konq_aboutpage"; + originalURL = req.typedURL.isEmpty() ? QString::null : url.url(); + // empty if from profile, about:konqueror if the user typed it (not req.typedURL, it could be "about:") + } + else if ( url.url() == "about:blank" && req.typedURL.isEmpty() ) + { + originalURL = QString::null; + } + + // Look for which view mode to use, if a directory - not if view locked + if ( ( !childView || (!childView->isLockedViewMode()) ) + && serviceType == "inode/directory" ) + { // Phew ! + + // Set view mode if necessary (current view doesn't support directories) + if ( !childView || !childView->supportsServiceType( serviceType ) ) + serviceName = KonqSettings::mainViewViewMode(); + + if ( url.isLocalFile() ) // local, we can do better (.directory) + { + // Read it in the .directory file, default to m_bHTMLAllowed + KURL urlDotDir( url ); + urlDotDir.addPath(".directory"); + bool HTMLAllowed = m_bHTMLAllowed; + QFile f( urlDotDir.path() ); + if ( f.open(IO_ReadOnly) ) + { + f.close(); + KSimpleConfig config( urlDotDir.path(), true ); + config.setGroup( "URL properties" ); + HTMLAllowed = config.readBoolEntry( "HTMLAllowed", m_bHTMLAllowed ); + serviceName = config.readEntry( "ViewMode", serviceName ); + kdDebug(1202) << "serviceName=" << serviceName << endl; + } + if ( HTMLAllowed && + ( ( indexFile = findIndexFile( url.path() ) ) != QString::null ) ) + { + serviceType = "text/html"; + url = KURL(); + url.setPath( indexFile ); + serviceName = QString::null; // cancel what we just set, this is not a dir finally + } + + // Reflect this setting in the menu + m_ptaUseHTML->setChecked( HTMLAllowed ); + } + } + + bool ok = true; + if ( !childView ) + { + if (req.newTab) + { + KonqFrameTabs* tabContainer = 0L; + int index = 0; + if ( m_pViewManager->docContainer() && m_pViewManager->docContainer()->frameType() == "Tabs") + { + tabContainer = static_cast<KonqFrameTabs*>(m_pViewManager->docContainer()); + index = tabContainer->currentPageIndex(); + } + childView = m_pViewManager->addTab( serviceType, serviceName, false, req.openAfterCurrentPage ); + + if (req.newTabInFront && childView) + { + if ( !tabContainer ) + tabContainer = static_cast<KonqFrameTabs*>(m_pViewManager->docContainer()); + if ( req.openAfterCurrentPage ) + tabContainer->setCurrentPage( index + 1 ); + else + tabContainer->setCurrentPage( tabContainer->count()-1 ); + } + } + + else + { + // Create a new view + // Initialize always uses force auto-embed even if user setting is "separate viewer", + // since this window has no view yet - we don't want to keep an empty mainwindow. + // This can happen with e.g. application/pdf from a target="_blank" link, or window.open. + childView = m_pViewManager->Initialize( serviceType, serviceName ); + + if ( childView ) + { + enableAllActions( true ); + m_currentView = childView; + } + } + + if ( !childView ) + return false; // It didn't work out. + + childView->setViewName( m_initialFrameName.isEmpty() ? req.args.frameName : m_initialFrameName ); + m_initialFrameName = QString::null; + } + else // We know the child view + { + if ( !childView->isLockedViewMode() ) + { + bool forceAutoEmbed = req.forceAutoEmbed || req.newTab || req.userRequestedReload; + if ( !req.typedURL.isEmpty() ) // the user _typed_ the URL, he wants it in Konq. + forceAutoEmbed = true; + if ( url.protocol() == "about" ) + forceAutoEmbed = true; + // Related to KonqFactory::createView + if ( !forceAutoEmbed && !KonqFMSettings::settings()->shouldEmbed( serviceType ) ) + { + kdDebug(1202) << "openView: KonqFMSettings says: don't embed this servicetype" << endl; + ok = false; + } + + // If the protocol doesn't support writing (e.g. HTTP) then we might want to save instead of just embedding. + // So (if embedding would succeed, hence the checks above) we ask the user + // Otherwise the user will get asked 'open or save' in openURL anyway. + if ( ok && !forceAutoEmbed && !KProtocolInfo::supportsWriting( url ) ) { + QString suggestedFilename; + + KonqRun* run = childView->run(); + int attachment = 0; + if (run) { + suggestedFilename = run->suggestedFilename(); + attachment = (run->serverSuggestsSave()) ? KParts::BrowserRun::AttachmentDisposition : KParts::BrowserRun::InlineDisposition; + } + + KParts::BrowserRun::AskSaveResult res = KParts::BrowserRun::askEmbedOrSave( + url, serviceType, suggestedFilename, attachment ); + if ( res == KParts::BrowserRun::Open ) + forceAutoEmbed = true; + else if ( res == KParts::BrowserRun::Cancel ) + return true; // handled, don't do anything else + else { // Save + KParts::BrowserRun::simpleSave( url, suggestedFilename, this ); + return true; // handled + } + } + if ( ok ) + ok = childView->changeViewMode( serviceType, serviceName, forceAutoEmbed ); + } + } + + if (ok) + { + //kdDebug(1202) << "req.nameFilter= " << req.nameFilter << endl; + //kdDebug(1202) << "req.typedURL= " << req.typedURL << endl; + //kdDebug(1202) << "Browser extension? " << (childView->browserExtension() ? "YES" : "NO") << endl; + //kdDebug(1202) << "Referrer: " << req.args.metaData()["referrer"] << endl; + childView->setTypedURL( req.typedURL ); + if ( childView->browserExtension() ) + childView->browserExtension()->setURLArgs( req.args ); + if ( childView->part()->inherits("KonqDirPart") ) + static_cast<KonqDirPart *>(childView->part())->setFilesToSelect( req.filesToSelect ); + if ( !url.isEmpty() ) + childView->openURL( url, originalURL, req.nameFilter, req.tempFile ); + } + kdDebug(1202) << "KonqMainWindow::openView ok=" << ok << " bOthersFollowed=" << bOthersFollowed << " returning " + << (ok || bOthersFollowed) + << endl; + return ok || bOthersFollowed; +} + +void KonqMainWindow::slotOpenURLRequest( const KURL &url, const KParts::URLArgs &args ) +{ + kdDebug(1202) << "KonqMainWindow::slotOpenURLRequest frameName=" << args.frameName << endl; + + KParts::ReadOnlyPart *callingPart = static_cast<KParts::ReadOnlyPart *>( sender()->parent() ); + QString frameName = args.frameName; + + if ( !frameName.isEmpty() ) + { + static QString _top = QString::fromLatin1( "_top" ); + static QString _self = QString::fromLatin1( "_self" ); + static QString _parent = QString::fromLatin1( "_parent" ); + static QString _blank = QString::fromLatin1( "_blank" ); + + if ( frameName.lower() == _blank ) + { + slotCreateNewWindow( url, args ); + return; + } + + if ( frameName.lower() != _top && + frameName.lower() != _self && + frameName.lower() != _parent ) + { + KParts::BrowserHostExtension *hostExtension = 0; + KonqView *view = childView( callingPart, frameName, &hostExtension, 0 ); + if ( !view ) + { + KonqMainWindow *mainWindow = 0; + view = findChildView( callingPart, frameName, &mainWindow, &hostExtension, 0 ); + + if ( !view || !mainWindow ) + { + slotCreateNewWindow( url, args ); + return; + } + + if ( hostExtension ) + hostExtension->openURLInFrame( url, args ); + else + mainWindow->openURL( view, url, args ); + return; + } + + if ( hostExtension ) + hostExtension->openURLInFrame( url, args ); + else + openURL( view, url, args ); + return; + } + } + + KonqView *view = childView( callingPart ); + openURL( view, url, args ); +} + +//Called by slotOpenURLRequest +void KonqMainWindow::openURL( KonqView *childView, const KURL &url, const KParts::URLArgs &args ) +{ + kdDebug(1202) << "KonqMainWindow::openURL (from slotOpenURLRequest) url=" << url.prettyURL() << endl; + KonqOpenURLRequest req; + req.args = args; + + // Clicking on a link that points to the page itself (e.g. anchor) + if ( !args.doPost() && !args.reload && + childView && urlcmp( url.url(), childView->url().url(), true, true ) ) + { + QString serviceType = args.serviceType; + if ( serviceType.isEmpty() ) + serviceType = childView->serviceType(); + + childView->stop(); + req.forceAutoEmbed = true; + + req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); + openView( serviceType, url, childView, req ); + return; + } + + openURL( childView, url, args.serviceType, req, args.trustedSource ); +} + +QObject *KonqMainWindow::lastFrame( KonqView *view ) +{ + QObject *nextFrame, *viewFrame; + nextFrame = view->frame(); + viewFrame = 0; + while ( nextFrame != 0 && ! nextFrame->inherits( "QWidgetStack" ) ) { + viewFrame = nextFrame; + nextFrame = nextFrame->parent(); + } + return nextFrame ? viewFrame : 0L; +} + +// Linked-views feature, plus "sidebar follows URL opened in the active view" feature +bool KonqMainWindow::makeViewsFollow( const KURL & url, const KParts::URLArgs &args, + const QString & serviceType, KonqView * senderView ) +{ + if ( !senderView->isLinkedView() && senderView != m_currentView ) + return false; // none of those features apply -> return + + bool res = false; + //kdDebug(1202) << "makeViewsFollow " << senderView->className() << " url=" << url << " serviceType=" << serviceType << endl; + KonqOpenURLRequest req; + req.followMode = true; + req.args = args; + // We can't iterate over the map here, and openURL for each, because the map can get modified + // (e.g. by part changes). Better copy the views into a list. + QPtrList<KonqView> listViews; + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + listViews.append( it.data() ); + + QObject *senderFrame = lastFrame( senderView ); + + for ( KonqView * view = listViews.first() ; view ; view = listViews.next()) + { + bool followed = false; + // Views that should follow this URL as both views are linked + if ( (view != senderView) && view->isLinkedView() && senderView->isLinkedView() ) + { + QObject *viewFrame = lastFrame( view ); + + // Only views in the same tab of the sender will follow + if ( senderFrame && viewFrame && viewFrame != senderFrame ) + continue; + + kdDebug(1202) << "makeViewsFollow: Sending openURL to view " << view->part()->className() << " url=" << url << endl; + + // XXX duplicate code from ::openURL + if ( view == m_currentView ) + { + abortLoading(); + setLocationBarURL( url ); + } + else + view->stop(); + + followed = openView( serviceType, url, view, req ); + } + else + { + // Make the sidebar follow the URLs opened in the active view + if ((view!=senderView) && view->isFollowActive() && senderView == m_currentView) + { + followed = openView(serviceType, url, view, req); + } + } + + // Ignore return value if the view followed but doesn't really + // show the file contents. We still want to see that + // file, e.g. in a separate viewer. + // This happens in views locked to a directory mode, + // like sidebar and konsolepart (#52161). + bool ignore = view->isLockedViewMode() && view->supportsServiceType("inode/directory"); + //kdDebug(1202) << "View " << view->service()->name() + // << " supports dirs: " << view->supportsServiceType( "inode/directory" ) + // << " is locked-view-mode:" << view->isLockedViewMode() + // << " ignore=" << ignore << endl; + if ( !ignore ) + res = followed || res; + } + + return res; +} + +void KonqMainWindow::abortLoading() +{ + //kdDebug(1202) << "KonqMainWindow::abortLoading()" << endl; + if ( m_currentView ) + { + m_currentView->stop(); // will take care of the statusbar + stopAnimation(); + } +} + +void KonqMainWindow::slotCreateNewWindow( const KURL &url, const KParts::URLArgs &args ) +{ + kdDebug(1202) << "KonqMainWindow::slotCreateNewWindow url=" << url.prettyURL() << endl; + + if ( args.newTab() || ( KonqSettings::mmbOpensTab() && + (const_cast<KParts::URLArgs*>(&args)->metaData()["forcenewwindow"]).isEmpty()) ) { + KonqOpenURLRequest req; + req.newTab = true; + req.newTabInFront = KonqSettings::newTabsInFront(); + req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); + + if (KApplication::keyboardMouseState() & Qt::ShiftButton) + req.newTabInFront = !req.newTabInFront; + req.args = args; + openURL( 0L, url, QString::null, req ); + } + else + { + KonqMisc::createNewWindow( url, args ); + } +} + +// This is mostly for the JS window.open call +void KonqMainWindow::slotCreateNewWindow( const KURL &url, const KParts::URLArgs &args, + const KParts::WindowArgs &windowArgs, KParts::ReadOnlyPart *&part ) +{ + kdDebug(1202) << "KonqMainWindow::slotCreateNewWindow(4 args) url=" << url.prettyURL() + << " args.serviceType=" << args.serviceType + << " args.frameName=" << args.frameName << endl; + + part = 0; // Make sure to be initialized in case of failure... + + KonqMainWindow *mainWindow = 0L; + if ( !args.frameName.isEmpty() && args.frameName.lower() != "_blank" ) + { + KParts::BrowserHostExtension *hostExtension = 0; + KParts::ReadOnlyPart *ro_part = 0L; + KParts::BrowserExtension *be = ::qt_cast<KParts::BrowserExtension *>(sender()); + if (be) + ro_part = ::qt_cast<KParts::ReadOnlyPart *>(be->parent()); + if ( findChildView( ro_part, args.frameName, &mainWindow, &hostExtension, &part ) ) + { + // Found a view. If url isn't empty, we should open it - but this never happens currently + // findChildView put the resulting part in 'part', so we can just return now + //kdDebug() << " frame=" << args.frameName << " -> found part=" << part << " " << part->name() << endl; + return; + } + } + + if ( KonqSettings::popupsWithinTabs() || ( KonqSettings::mmbOpensTab() && windowArgs.lowerWindow ) ) { + bool aftercurrentpage = KonqSettings::openAfterCurrentPage(); + bool newtabsinfront = KonqSettings::newTabsInFront(); + if ( windowArgs.lowerWindow ) + newtabsinfront =! newtabsinfront; + + KonqView* newView = m_pViewManager->addTab(QString::null, QString::null, false, aftercurrentpage); + if (newView == 0L) return; + + if (newtabsinfront) + m_pViewManager->showTab( newView ); + + openURL( newView, url.isEmpty() ? KURL("about:blank") : url, QString::null); + newView->setViewName( args.frameName ); + part=newView->part(); + + return; + } + + mainWindow = new KonqMainWindow( KURL(), false ); + mainWindow->setInitialFrameName( args.frameName ); + mainWindow->resetAutoSaveSettings(); // Don't autosave + + KonqOpenURLRequest req; + req.args = args; + + if ( args.serviceType.isEmpty() ) + mainWindow->openURL( 0L, url, QString::null, req ); + else if ( !mainWindow->openView( args.serviceType, url, 0L, req ) ) + { + // we have problems. abort. + delete mainWindow; + part = 0; + return; + } + + KonqView * view = 0L; + // cannot use activePart/currentView, because the activation through the partmanager + // is delayed by a singleshot timer (see KonqViewManager::setActivePart) + if ( mainWindow->viewMap().count() ) + { + MapViews::ConstIterator it = mainWindow->viewMap().begin(); + view = it.data(); + part = it.key(); + } + + // activate the view _now_ in order to make the menuBar() hide call work + if ( part ) { + mainWindow->viewManager()->setActivePart( part, true ); + } + + QString profileName = QString::fromLatin1( url.isLocalFile() ? "konqueror/profiles/filemanagement" : "konqueror/profiles/webbrowsing" ); + KSimpleConfig cfg( locate( "data", profileName ), true ); + cfg.setGroup( "Profile" ); + + if ( windowArgs.x != -1 ) + mainWindow->move( windowArgs.x, mainWindow->y() ); + if ( windowArgs.y != -1 ) + mainWindow->move( mainWindow->x(), windowArgs.y ); + + QSize size = KonqViewManager::readConfigSize( cfg, mainWindow ); + + int width; + if ( windowArgs.width != -1 ) + width = windowArgs.width; + else + width = size.isValid() ? size.width() : mainWindow->width(); + + int height; + if ( windowArgs.height != -1 ) + height = windowArgs.height; + else + height = size.isValid() ? size.height() : mainWindow->height(); + + mainWindow->resize( width, height ); + + // process the window args + + if ( !windowArgs.menuBarVisible ) + { + mainWindow->menuBar()->hide(); + mainWindow->m_paShowMenuBar->setChecked( false ); + } + + if ( !windowArgs.toolBarsVisible ) + { + for ( QPtrListIterator<KToolBar> it( mainWindow->toolBarIterator() ); it.current(); ++it ) + { + (*it)->hide(); + } + } + + if ( view ) { + if ( !windowArgs.scrollBarsVisible ) + view->disableScrolling(); + if ( !windowArgs.statusBarVisible ) + view->frame()->statusbar()->hide(); + } + + if ( !windowArgs.resizable ) + // ### this doesn't seem to work :-( + mainWindow->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + +// Trying to show the window initially behind the current window is a bit tricky, +// as this involves the window manager, which may see things differently. +// Many WMs raise and activate new windows, which means without WM support this won't work very +// well. If the WM has support for _NET_WM_USER_TIME, it will be just set to 0 (=don't focus on show), +// and the WM should take care of it itself. + bool wm_usertime_support = false; + extern Time qt_x_user_time; + Time saved_last_input_time = qt_x_user_time; + if ( windowArgs.lowerWindow ) + { + NETRootInfo wm_info( qt_xdisplay(), NET::Supported ); + wm_usertime_support = wm_info.isSupported( NET::WM2UserTime ); + if( wm_usertime_support ) + { + // *sigh*, and I thought nobody would need QWidget::dontFocusOnShow(). + // Avoid Qt's support for user time by setting it to 0, and + // set the property ourselves. + qt_x_user_time = 0; + KWin::setUserTime( mainWindow->winId(), 0 ); + } + // Put below the current window before showing, in case that actually works with the WM. + // First do complete lower(), then stackUnder(), because the latter may not work with many WMs. + mainWindow->lower(); + mainWindow->stackUnder( this ); + } + + mainWindow->show(); + + if ( windowArgs.lowerWindow ) + { + qt_x_user_time = saved_last_input_time; + if( !wm_usertime_support ) + { // No WM support. Let's try ugly tricks. + mainWindow->lower(); + mainWindow->stackUnder( this ); + if( this->isActiveWindow()) + this->setActiveWindow(); + } + } + + if ( windowArgs.fullscreen ) + mainWindow->action( "fullscreen" )->activate(); +} + +void KonqMainWindow::slotNewWindow() +{ + // Use profile from current window, if set + QString profile = m_pViewManager->currentProfile(); + if ( profile.isEmpty() ) + { + if ( m_currentView && m_currentView->url().protocol().startsWith( "http" ) ) + profile = QString::fromLatin1("webbrowsing"); + else + profile = QString::fromLatin1("filemanagement"); + } + KonqMisc::createBrowserWindowFromProfile( + locate( "data", QString::fromLatin1("konqueror/profiles/")+profile ), + profile ); +} + +void KonqMainWindow::slotDuplicateWindow() +{ + KTempFile tempFile; + tempFile.setAutoDelete( true ); + KConfig config( tempFile.name() ); + config.setGroup( "View Profile" ); + m_pViewManager->saveViewProfile( config, true, true ); + + KonqMainWindow *mainWindow = new KonqMainWindow( KURL(), false, 0, xmlFile()); + mainWindow->viewManager()->loadViewProfile( config, m_pViewManager->currentProfile() ); + if (mainWindow->currentView()) + { + mainWindow->copyHistory( childFrame() ); + } + mainWindow->activateChild(); + mainWindow->show(); +#ifndef NDEBUG + mainWindow->viewManager()->printFullHierarchy( this ); +#endif +} + +void KonqMainWindow::slotSendURL() +{ + KURL::List lst = currentURLs(); + QString body; + QString fileNameList; + for ( KURL::List::Iterator it = lst.begin() ; it != lst.end() ; ++it ) + { + if ( !body.isEmpty() ) body += '\n'; + body += (*it).prettyURL(); + if ( !fileNameList.isEmpty() ) fileNameList += ", "; + fileNameList += (*it).fileName(); + } + QString subject; + if ( m_currentView && !m_currentView->part()->inherits("KonqDirPart") ) + subject = m_currentView->caption(); + else + subject = fileNameList; + kapp->invokeMailer(QString::null,QString::null,QString::null, + subject, body); +} + +void KonqMainWindow::slotSendFile() +{ + KURL::List lst = currentURLs(); + QStringList urls; + QString fileNameList; + for ( KURL::List::Iterator it = lst.begin() ; it != lst.end() ; ++it ) + { + if ( !fileNameList.isEmpty() ) fileNameList += ", "; + if ( (*it).isLocalFile() && QFileInfo((*it).path()).isDir() ) + { + // Create a temp dir, so that we can put the ZIP file in it with a proper name + KTempFile zipFile; + QString zipFileName = zipFile.name(); + zipFile.unlink(); + + QDir().mkdir(zipFileName,true); + zipFileName = zipFileName+"/"+(*it).fileName()+".zip"; + KZip zip( zipFileName ); + if ( !zip.open( IO_WriteOnly ) ) + continue; // TODO error message + zip.addLocalDirectory( (*it).path(), QString::null ); + zip.close(); + fileNameList += (*it).fileName()+".zip"; + urls.append( zipFileName ); + } + else + { + fileNameList += (*it).fileName(); + urls.append( (*it).url() ); + } + } + QString subject; + if ( m_currentView && !m_currentView->part()->inherits("KonqDirPart") ) + subject = m_currentView->caption(); + else + subject = fileNameList; + kapp->invokeMailer(QString::null, QString::null, QString::null, subject, + QString::null, //body + QString::null, + urls); // attachments +} + +void KonqMainWindow::slotOpenTerminal() +{ + QString term = KonqSettings::terminalApplication(); + + QString dir ( QDir::homeDirPath() ); + + //Try to get the directory of the current view + if ( m_currentView ) + { + KURL u( m_currentView->url() ); + + // If the given directory is not local, it can still be the URL of an + // ioslave using UDS_LOCAL_PATH which to be converted first. + u = KIO::NetAccess::mostLocalURL(u, this); + + //If the URL is local after the above conversion, set the directory. + if ( u.isLocalFile() ) + { + QString mime = m_currentView->serviceType(); + if ( KMimeType::mimeType(mime)->is("inode/directory") ) + dir = u.path(); + else + dir = u.directory(); + } + } + + KProcess cmd; + cmd.setWorkingDirectory(dir); + + // Compensate for terminal having arguments. + QStringList args = QStringList::split(' ', term); + for ( QStringList::iterator it = args.begin(); it != args.end(); ++it ) + cmd << *it; + + kdDebug(1202) << "slotOpenTerminal: directory " << dir + << ", terminal:" << term << endl; + cmd.start(KProcess::DontCare); +} + +void KonqMainWindow::slotOpenLocation() +{ + // Don't pre-fill the url, as it is auto-selected and thus overwrites the + // X clipboard, making it impossible to paste in the url you really wanted. + // Another example of why the X clipboard sux + KURLRequesterDlg dlg( QString::null, this, 0, true); + dlg.setCaption( i18n("Open Location") ); + // Set current directory for relative paths. + // Testcase: konqueror www.kde.org; Ctrl+O; file in $HOME; would open http://$file + QString currentDir; + if (m_currentView && m_currentView->url().isLocalFile()) + currentDir = m_currentView->url().path(1); + dlg.urlRequester()->completionObject()->setDir( currentDir ); + dlg.urlRequester()->setMode( KFile::File | KFile::Directory | KFile::ExistingOnly ); + dlg.exec(); + const KURL& url = dlg.selectedURL(); + if (!url.isEmpty()) + openFilteredURL( url.url().stripWhiteSpace() ); +} + +void KonqMainWindow::slotToolFind() +{ + kdDebug(1202) << "KonqMainWindow::slotToolFind sender:" << sender()->className() << endl; + + if ( m_currentView && m_currentView->part()->inherits("KonqDirPart") ) + { + KonqDirPart* dirPart = static_cast<KonqDirPart *>(m_currentView->part()); + + if (!m_paFindFiles->isChecked()) + { + dirPart->slotFindClosed(); + return; + } + + KonqViewFactory factory = KonqFactory::createView( "Konqueror/FindPart" ); + if ( factory.isNull() ) + { + KMessageBox::error( this, i18n("Cannot create the find part, check your installation.") ); + m_paFindFiles->setChecked(false); + return; + } + + KParts::ReadOnlyPart* findPart = factory.create( m_currentView->frame(), "findPartWidget", dirPart, "findPart" ); + dirPart->setFindPart( findPart ); + + m_currentView->frame()->insertTopWidget( findPart->widget() ); + findPart->widget()->show(); + findPart->widget()->setFocus(); + + connect( dirPart, SIGNAL( findClosed(KonqDirPart *) ), + this, SLOT( slotFindClosed(KonqDirPart *) ) ); + } + else if ( sender()->inherits( "KAction" ) ) // don't go there if called by the singleShot below + { + KURL url; + if ( m_currentView && m_currentView->url().isLocalFile() ) + url = m_currentView->locationBarURL(); + else + url.setPath( QDir::homeDirPath() ); + KonqMainWindow * mw = KonqMisc::createBrowserWindowFromProfile( + locate( "data", QString::fromLatin1("konqueror/profiles/filemanagement") ), + "filemanagement", url, KParts::URLArgs(), true /* forbid "use html"*/ ); + mw->m_paFindFiles->setChecked(true); + // Delay it after the openURL call (hacky!) + QTimer::singleShot( 1, mw, SLOT(slotToolFind())); + m_paFindFiles->setChecked(false); + } +} + +void KonqMainWindow::slotFindOpen( KonqDirPart * dirPart ) +{ + kdDebug(1202) << "KonqMainWindow::slotFindOpen " << dirPart << endl; + Q_ASSERT( m_currentView ); + Q_ASSERT( m_currentView->part() == dirPart ); + slotToolFind(); // lazy me +} + +void KonqMainWindow::slotFindClosed( KonqDirPart * dirPart ) +{ + kdDebug(1202) << "KonqMainWindow::slotFindClosed " << dirPart << endl; + KonqView * dirView = m_mapViews.find( dirPart ).data(); + Q_ASSERT(dirView); + kdDebug(1202) << "dirView=" << dirView << endl; + if ( dirView && dirView == m_currentView ) + m_paFindFiles->setEnabled( true ); + m_paFindFiles->setChecked(false); +} + +void KonqMainWindow::slotIconsChanged() +{ + //kdDebug(1202) << "KonqMainWindow::slotIconsChanged" << endl; + m_combo->updatePixmaps(); + m_pViewManager->updatePixmaps(); + setIcon( KonqPixmapProvider::self()->pixmapFor( m_combo->currentText() )); +} + +void KonqMainWindow::slotOpenWith() +{ + KURL::List lst; + lst.append( m_currentView->url() ); + + QString serviceName = sender()->name(); + + KTrader::OfferList offers = m_currentView->appServiceOffers(); + KTrader::OfferList::ConstIterator it = offers.begin(); + KTrader::OfferList::ConstIterator end = offers.end(); + for (; it != end; ++it ) + if ( (*it)->desktopEntryName() == serviceName ) + { + KRun::run( **it, lst ); + return; + } +} + +void KonqMainWindow::slotViewModeToggle( bool toggle ) +{ + if ( !toggle ) + return; + + QString modeName = sender()->name(); + + if ( m_currentView->service()->desktopEntryName() == modeName ) + return; + + m_bViewModeToggled = true; + + m_currentView->stop(); + m_currentView->lockHistory(); + + // Save those, because changeViewMode will lose them + KURL url = m_currentView->url(); + QString locationBarURL = m_currentView->locationBarURL(); + QStringList filesToSelect; + if( m_currentView->part()->inherits( "KonqDirPart" ) ) { + KFileItemList fileItemsToSelect = static_cast<KonqDirPart*>(m_currentView->part())->selectedFileItems(); + KFileItemListIterator it( fileItemsToSelect ); + while( it.current() ){ + filesToSelect += it.current()->name(); + ++it; + } + } + + + bool bQuickViewModeChange = false; + + // iterate over all services, update the toolbar service map + // and check if we can do a quick property-based viewmode change + const KTrader::OfferList offers = m_currentView->partServiceOffers(); + KTrader::OfferList::ConstIterator oIt = offers.begin(); + KTrader::OfferList::ConstIterator oEnd = offers.end(); + const QString currentServiceKey = viewModeActionKey( m_currentView->service() ); + for (; oIt != oEnd; ++oIt ) + { + KService::Ptr service = *oIt; + + if ( service->desktopEntryName() == modeName ) + { + // we changed the viewmode of either iconview or listview + // -> update the service in the corresponding map, so that + // we can set the correct text, icon, etc. properties to the + // KonqViewModeAction when rebuilding the view-mode actions in + // updateViewModeActions + // (I'm saying iconview/listview here, but theoretically it could be + // any view :) + const QString serviceKey = viewModeActionKey( service ); + m_viewModeToolBarServices[ serviceKey ] = service; + + if ( serviceKey == currentServiceKey ) + { + QVariant modeProp = service->property( "X-KDE-BrowserView-ModeProperty" ); + QVariant modePropValue = service->property( "X-KDE-BrowserView-ModePropertyValue" ); + if ( !modeProp.isValid() || !modePropValue.isValid() ) + break; + + m_currentView->part()->setProperty( modeProp.toString().latin1(), modePropValue ); + + KService::Ptr oldService = m_currentView->service(); + + // we aren't going to re-build the viewmode actions but instead of a + // quick viewmode change (iconview) -> find the iconview-konqviewmode + // action and set new text,icon,etc. properties, to show the new + // current viewmode + QPtrListIterator<KAction> it( m_toolBarViewModeActions ); + for (; it.current(); ++it ) + if ( QString::fromLatin1( it.current()->name() ) == oldService->desktopEntryName() ) + { + assert( it.current()->inherits( "KonqViewModeAction" ) ); + + KonqViewModeAction *action = static_cast<KonqViewModeAction *>( it.current() ); + + action->setChecked( true ); + QString servicename = service->genericName(); + if (servicename.isEmpty()) + servicename = service->name(); + action->setText( servicename ); + action->setIcon( service->icon() ); + action->setName( service->desktopEntryName().ascii() ); + + break; + } + + m_currentView->setService( service ); + + bQuickViewModeChange = true; + break; + } + } + } + + if ( !bQuickViewModeChange ) + { + m_currentView->changeViewMode( m_currentView->serviceType(), modeName ); + KURL locURL = KURL::fromPathOrURL( locationBarURL ); + QString nameFilter = detectNameFilter( locURL ); + if( m_currentView->part()->inherits( "KonqDirPart" ) ) + static_cast<KonqDirPart*>( m_currentView->part() )->setFilesToSelect( filesToSelect ); + m_currentView->openURL( locURL, locationBarURL, nameFilter ); + } + + // Now save this setting, either locally or globally (for directories only) + // (We don't have views with viewmodes other than for dirs currently; + // once we do, we might want to implement per-mimetype global-saving) + if ( m_bSaveViewPropertiesLocally && m_currentView->supportsServiceType( "inode/directory" ) ) + { + KURL u ( m_currentView->url() ); + u.addPath(".directory"); + if ( u.isLocalFile() ) + { + KSimpleConfig config( u.path() ); // if we have no write access, just drop it + config.setGroup( "URL properties" ); + config.writeEntry( "ViewMode", modeName ); + config.sync(); + } + } else + { + // We save the global view mode only if the view is a built-in view + if ( m_currentView->isBuiltinView() ) + { + KonqSettings::setMainViewViewMode( modeName ); + KonqSettings::writeConfig(); + } + } +} + +void KonqMainWindow::showHTML( KonqView * _view, bool b, bool _activateView ) +{ + // Save this setting, either locally or globally + // This has to be done before calling openView since it relies on it + if ( m_bSaveViewPropertiesLocally ) + { + KURL u ( b ? _view->url() : KURL( _view->url().directory() ) ); + u.addPath(".directory"); + if ( u.isLocalFile() ) + { + KSimpleConfig config( u.path() ); // No checks for access + config.setGroup( "URL properties" ); + config.writeEntry( "HTMLAllowed", b ); + config.sync(); + } + } else + { + KonqSettings::setHtmlAllowed( b ); + KonqSettings::writeConfig(); + if ( _activateView ) + m_bHTMLAllowed = b; + } + + if ( b && _view->supportsServiceType( "inode/directory" ) ) + { + _view->lockHistory(); + openView( "inode/directory", _view->url(), _view ); + } + else if ( !b && _view->supportsServiceType( "text/html" ) ) + { + KURL u( _view->url() ); + QString fileName = u.fileName().lower(); + if ( KProtocolInfo::supportsListing( u ) && fileName.startsWith("index.htm") ) { + _view->lockHistory(); + u.setPath( u.directory() ); + openView( "inode/directory", u, _view ); + } + } +} + +void KonqMainWindow::slotShowHTML() +{ + bool b = !m_currentView->allowHTML(); + + m_currentView->stop(); + m_currentView->setAllowHTML( b ); + showHTML( m_currentView, b, true ); //current view + m_pViewManager->showHTML(b ); + +} + +void KonqMainWindow::setShowHTML( bool b ) +{ + m_bHTMLAllowed = b; + if ( m_currentView ) + m_currentView->setAllowHTML( b ); + m_ptaUseHTML->setChecked( b ); +} + +void KonqMainWindow::slotLockView() +{ + m_currentView->setLockedLocation( m_paLockView->isChecked() ); +} + +void KonqMainWindow::slotStop() +{ + abortLoading(); + if ( m_currentView ) + { + m_currentView->frame()->statusbar()->message( i18n("Canceled.") ); + } +} + +void KonqMainWindow::slotLinkView() +{ + // Can't access this action in passive mode anyway + assert(!m_currentView->isPassiveMode()); + bool mode = !m_currentView->isLinkedView(); + + if (linkableViewsCount() == 2) + { + // Exactly two linkable views : link both + KonqMainWindow::MapViews::ConstIterator it = viewMap().begin(); + if( (*it)->isFollowActive() ) // skip sidebar + ++it; + (*it)->setLinkedView( mode ); + ++it; + if( (*it)->isFollowActive() ) // skip sidebar + ++it; + (*it)->setLinkedView( mode ); + } + else // Normal case : just this view + m_currentView->setLinkedView( mode ); +} + +void KonqMainWindow::slotReload( KonqView* reloadView ) +{ + if ( !reloadView ) + reloadView = m_currentView; + + if ( !reloadView || reloadView->url().isEmpty() ) + return; + + if ( reloadView->part() && (reloadView->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = reloadView->part()->property("modified"); + if (prop.isValid() && prop.toBool()) + if ( KMessageBox::warningContinueCancel( this, + i18n("This page contains changes that have not been submitted.\nReloading the page will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"reload"), "discardchangesreload") != KMessageBox::Continue ) + return; + } + + KonqOpenURLRequest req( reloadView->typedURL() ); + req.userRequestedReload = true; + if ( reloadView->prepareReload( req.args ) ) + { + reloadView->lockHistory(); + // Reuse current servicetype for local files, but not for remote files (it could have changed, e.g. over HTTP) + QString serviceType = reloadView->url().isLocalFile() ? reloadView->serviceType() : QString::null; + openURL( reloadView, reloadView->url(), serviceType, req ); + } +} + +void KonqMainWindow::slotReloadPopup() +{ + if (m_pWorkingTab) + slotReload( m_pWorkingTab->activeChildView() ); +} + +void KonqMainWindow::slotHome(KAction::ActivationReason, Qt::ButtonState state) +{ + QString homeURL = m_pViewManager->profileHomeURL(); + + if (homeURL.isEmpty()) + homeURL = KonqFMSettings::settings()->homeURL(); + + KonqOpenURLRequest req; + req.newTab = true; + req.newTabInFront = KonqSettings::newTabsInFront(); + + if (state & Qt::ShiftButton) + req.newTabInFront = !req.newTabInFront; + + if( state & Qt::ControlButton ) // Ctrl Left/MMB + openFilteredURL( homeURL, req); + else if( state & Qt::MidButton ) + { + if(KonqSettings::mmbOpensTab()) + openFilteredURL( homeURL, req); + else + { + KURL finalURL = KonqMisc::konqFilteredURL( this, homeURL ); + KonqMisc::createNewWindow( finalURL.url() ); + } + } + else + openFilteredURL( homeURL, false ); +} + + +void KonqMainWindow::slotHome() +{ + slotHome(KAction::UnknownActivation, Qt::LeftButton); +} + +void KonqMainWindow::slotGoSystem() +{ + openURL( 0L, KURL( "system:/" ) ); +} + +void KonqMainWindow::slotGoApplications() +{ + openURL( 0L, KURL( "programs:/" ) ); +} + +void KonqMainWindow::slotGoMedia() +{ + openURL( 0L, KURL( "media:/" ) ); +} + +void KonqMainWindow::slotGoNetworkFolders() +{ + openURL( 0L, KURL( "remote:/" ) ); +} + +void KonqMainWindow::slotGoSettings() +{ + openURL( 0L, KURL( "settings:/" ) ); +} + +void KonqMainWindow::slotGoDirTree() +{ + KURL u; + u.setPath( locateLocal( "data", "konqueror/dirtree/" ) ); + openURL( 0L, u ); +} + +void KonqMainWindow::slotGoTrash() +{ + openURL( 0L, KURL( "trash:/" ) ); +} + +void KonqMainWindow::slotGoAutostart() +{ + KURL u; + u.setPath( KGlobalSettings::autostartPath() ); + openURL( 0L, u ); +} + +void KonqMainWindow::slotGoHistory() +{ + KAction *a = m_toggleViewGUIClient->action("konq_sidebartng"); + if (!a) { + KMessageBox::sorry(0L, i18n("Your sidebar is not functional or unavailable."), i18n("Show History Sidebar")); + return; + } + + // Show the sidebar + if (!static_cast<KToggleAction*>(a)->isChecked()) { + a->activate(); + QTimer::singleShot( 0, this, SLOT(slotGoHistory())); + return; + } + + // Tell it to show the history plugin + MapViews::ConstIterator it; + for (it = viewMap().begin(); it != viewMap().end(); ++it) { + KonqView *view = it.data(); + if (view) { + KService::Ptr svc = view->service(); + if (svc->desktopEntryName() == "konq_sidebartng") { + if (!view->part()->openURL("sidebar:history.desktop")) + KMessageBox::sorry(0L, i18n("Cannot find running history plugin in your sidebar."), i18n("Show History Sidebar")); + break; + } + } + } +} + +QStringList KonqMainWindow::configModules() const +{ + return m_configureModules; +} + +void KonqMainWindow::slotConfigureExtensions() +{ + KonqExtensionManager extensionManager(0, this, m_currentView ? m_currentView->part() : 0); + extensionManager.exec(); +} + +void KonqMainWindow::slotConfigure() +{ + if( !m_configureDialog ) + { + m_configureDialog = new KCMultiDialog( this, "configureDialog" ); + + QStringList modules = configModules(); + QStringList::ConstIterator end( modules.end() ); + + for( QStringList::ConstIterator it = modules.begin(); + it != end; ++it ) + { + if ( kapp->authorizeControlModule( *it ) ) + { + m_configureDialog->addModule( *it ); + } + } + + } + + m_configureDialog->show(); + +} + +void KonqMainWindow::slotConfigureSpellChecking() +{ + KApplication::startServiceByDesktopName("spellchecking"); +} + +void KonqMainWindow::slotConfigureToolbars() +{ + if ( autoSaveSettings() ) + saveMainWindowSettings( KGlobal::config(), "KonqMainWindow" ); + KEditToolbar dlg(factory()); + connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(slotNewToolbarConfig())); + connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(initBookmarkBar())); + dlg.exec(); +} + +void KonqMainWindow::slotNewToolbarConfig() // This is called when OK or Apply is clicked +{ + if ( m_toggleViewGUIClient ) + plugActionList( QString::fromLatin1( "toggleview" ), m_toggleViewGUIClient->actions() ); + if ( m_currentView && m_currentView->appServiceOffers().count() > 0 ) + plugActionList( "openwith", m_openWithActions ); + + plugViewModeActions(); + + applyMainWindowSettings( KGlobal::config(), "KonqMainWindow" ); +} + +void KonqMainWindow::slotUndoAvailable( bool avail ) +{ + bool enable = false; + + if ( avail && m_currentView && m_currentView->part() ) + { + // Avoid qWarning from QObject::property if it doesn't exist + if ( m_currentView->part()->metaObject()->findProperty( "supportsUndo" ) != -1 ) + { + QVariant prop = m_currentView->part()->property( "supportsUndo" ); + if ( prop.isValid() && prop.toBool() ) + enable = true; + } + } + + m_paUndo->setEnabled( enable ); +} + +void KonqMainWindow::slotPartChanged( KonqView *childView, KParts::ReadOnlyPart *oldPart, KParts::ReadOnlyPart *newPart ) +{ + kdDebug(1202) << "KonqMainWindow::slotPartChanged" << endl; + m_mapViews.remove( oldPart ); + m_mapViews.insert( newPart, childView ); + + // Remove the old part, and add the new part to the manager + // Note: this makes the new part active... so it calls slotPartActivated + + m_pViewManager->replacePart( oldPart, newPart, false ); + // Set active immediately + m_pViewManager->setActivePart( newPart, true ); + + viewsChanged(); +} + + +void KonqMainWindow::slotRunFinished() +{ + kdDebug(1202) << "KonqMainWindow::slotRunFinished()" << endl; + const KonqRun *run = static_cast<const KonqRun *>( sender() ); + + if ( run == m_initialKonqRun ) + m_initialKonqRun = 0L; + + if ( !run->mailtoURL().isEmpty() ) + { + kapp->invokeMailer( run->mailtoURL() ); + } + + if ( run->hasError() ) { // we had an error + QByteArray data; + QDataStream s( data, IO_WriteOnly ); + s << run->url().prettyURL() << kapp->dcopClient()->defaultObject(); + kapp->dcopClient()->send( "konqueror*", "KonquerorIface", + "removeFromCombo(QString,QCString)", data); + } + + KonqView *childView = run->childView(); + + // Check if we found a mimetype _and_ we got no error (example: cancel in openwith dialog) + if ( run->foundMimeType() && !run->hasError() ) + { + + // We do this here and not in the constructor, because + // we are waiting for the first view to be set up before doing this... + // Note: this is only used when konqueror is started from command line..... + if ( m_bNeedApplyKonqMainWindowSettings ) + { + m_bNeedApplyKonqMainWindowSettings = false; // only once + applyKonqMainWindowSettings(); + } + + return; + } + + if ( childView ) + { + childView->setLoading( false ); + + if ( childView == m_currentView ) + { + stopAnimation(); + + // Revert to working URL - unless the URL was typed manually + kdDebug(1202) << " typed URL = " << run->typedURL() << endl; + if ( run->typedURL().isEmpty() && childView->history().current() ) // not typed + childView->setLocationBarURL( childView->history().current()->locationBarURL ); + } + } + else // No view, e.g. empty webbrowsing profile + stopAnimation(); +} + +void KonqMainWindow::applyKonqMainWindowSettings() +{ + QStringList toggableViewsShown = KonqSettings::toggableViewsShown(); + QStringList::ConstIterator togIt = toggableViewsShown.begin(); + QStringList::ConstIterator togEnd = toggableViewsShown.end(); + for ( ; togIt != togEnd ; ++togIt ) + { + // Find the action by name + // KAction * act = m_toggleViewGUIClient->actionCollection()->action( (*togIt).latin1() ); + KAction *act = m_toggleViewGUIClient->action( *togIt ); + if ( act ) + act->activate(); + else + kdWarning(1202) << "Unknown toggable view in ToggableViewsShown " << *togIt << endl; + } +} + +void KonqMainWindow::slotSetStatusBarText( const QString & ) +{ + // Reimplemented to disable KParts::MainWindow default behaviour + // Does nothing here, see konq_frame.cc +} + +void KonqMainWindow::slotViewCompleted( KonqView * view ) +{ + assert( view ); + + // Need to update the current working directory + // of the completion object every time the user + // changes the directory!! (DA) + if( m_pURLCompletion ) + { + KURL u( view->locationBarURL() ); + if( u.isLocalFile() ) + m_pURLCompletion->setDir( u.path() ); + else + m_pURLCompletion->setDir( u.url() ); //needs work!! (DA) + } +} + +void KonqMainWindow::slotPartActivated( KParts::Part *part ) +{ + kdDebug(1202) << "KonqMainWindow::slotPartActivated " << part << " " + << ( part && part->instance() && part->instance()->aboutData() ? part->instance()->aboutData()->appName() : "" ) << endl; + + KonqView *newView = 0; + KonqView *oldView = m_currentView; + + if ( part ) + { + newView = m_mapViews.find( static_cast<KParts::ReadOnlyPart *>( part ) ).data(); + + if ( newView->isPassiveMode() ) + { + // Passive view. Don't connect anything, don't change m_currentView + // Another view will become the current view very soon + kdDebug(1202) << "KonqMainWindow::slotPartActivated: Passive mode - return" << endl; + return; + } + } + + KParts::BrowserExtension *ext = 0; + + if ( oldView ) + { + ext = oldView->browserExtension(); + if ( ext ) + { + //kdDebug(1202) << "Disconnecting extension for view " << oldView << endl; + disconnectExtension( ext ); + } + + if ( oldView->part() ) + { + KActionCollection *coll = oldView->part()->actionCollection(); + if ( coll ) + disconnectActionCollection( coll ); + } + } + + kdDebug(1202) << "KonqMainWindow::slotPartActivated: New current view " << newView << endl; + m_currentView = newView; + if ( !part ) + { + kdDebug(1202) << "KonqMainWindow::slotPartActivated: No part activated - returning" << endl; + unplugViewModeActions(); + createGUI( 0L ); + KParts::MainWindow::setCaption( "" ); + KParts::MainWindow::setIcon( kapp->icon()); + return; + } + + ext = m_currentView->browserExtension(); + + if ( ext ) + { + connectExtension( ext ); + } + else + { + kdDebug(1202) << "KonqMainWindow::slotPartActivated: No Browser Extension for the new part" << endl; + // Disable all browser-extension actions + + KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); + KParts::BrowserExtension::ActionSlotMap::ConstIterator it = actionSlotMap->begin(); + KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd = actionSlotMap->end(); + + for ( ; it != itEnd ; ++it ) + { + KAction * act = actionCollection()->action( it.key() ); + Q_ASSERT(act); + if (act) + act->setEnabled( false ); + } + + if ( m_paCopyFiles ) + m_paCopyFiles->setEnabled( false ); + if ( m_paMoveFiles ) + m_paMoveFiles->setEnabled( false ); + if ( m_paNewDir ) + m_paNewDir->setEnabled( false ); + } + createGUI( part ); + + KActionCollection *coll = m_currentView->part()->actionCollection(); + if ( coll ) + connectActionCollection( coll ); + + // View-dependent GUI + + KParts::MainWindow::setCaption( m_currentView->caption() ); + m_currentView->frame()->setTitle( m_currentView->caption() , 0L); + updateOpenWithActions(); + updateLocalPropsActions(); + updateViewActions(); // undo, lock, link and other view-dependent actions + + if ( m_bViewModeToggled ) + { + // if we just toggled the view mode via the view mode actions, then + // we don't need to do all the time-taking stuff below (Simon) + const QString currentServiceDesktopEntryName = m_currentView->service()->desktopEntryName(); + QPtrListIterator<KRadioAction> it( m_viewModeActions ); + for (; it.current(); ++it ) { + if ( it.current()->name() == currentServiceDesktopEntryName ) { + it.current()->setChecked( true ); + break; + } + } + const QString currentServiceLibrary = viewModeActionKey( m_currentView->service() ); + QPtrListIterator<KAction> ittb( m_toolBarViewModeActions ); + for (; ittb.current(); ++ittb ) { + KService::Ptr serv = KService::serviceByDesktopName( ittb.current()->name() ); + if ( serv && viewModeActionKey( serv ) == currentServiceLibrary ) { + KToggleAction* ta = static_cast<KToggleAction*>( ittb.current() ); + ta->setChecked( true ); + QString servicename = m_currentView->service()->genericName(); + if (servicename.isEmpty()) + servicename = m_currentView->service()->name(); + ta->setText( servicename ); + ta->setIcon( m_currentView->service()->icon() ); + ta->setName( m_currentView->service()->desktopEntryName().ascii() ) ; + break; + } + } + } + else + { + updateViewModeActions(); + } + + m_bViewModeToggled = false; + + + m_pMenuNew->setEnabled( m_currentView->supportsServiceType( "inode/directory" ) ); + + m_currentView->frame()->statusbar()->updateActiveStatus(); + + if ( oldView && oldView->frame() ) + oldView->frame()->statusbar()->updateActiveStatus(); + + //kdDebug(1202) << "KonqMainWindow::slotPartActivated: setting location bar url to " + // << m_currentView->locationBarURL() << " m_currentView=" << m_currentView << endl; + m_currentView->setLocationBarURL( m_currentView->locationBarURL() ); + + updateToolBarActions(); + + m_currentView->setActiveInstance(); +} + +void KonqMainWindow::insertChildView( KonqView *childView ) +{ + kdDebug(1202) << "KonqMainWindow::insertChildView " << childView << endl; + m_mapViews.insert( childView->part(), childView ); + + connect( childView, SIGNAL( viewCompleted( KonqView * ) ), + this, SLOT( slotViewCompleted( KonqView * ) ) ); + + if ( !m_pViewManager->isLoadingProfile() ) // see KonqViewManager::loadViewProfile + viewCountChanged(); + emit viewAdded( childView ); +} + +// Called by KonqViewManager, internal +void KonqMainWindow::removeChildView( KonqView *childView ) +{ + kdDebug(1202) << "KonqMainWindow::removeChildView childView " << childView << endl; + + disconnect( childView, SIGNAL( viewCompleted( KonqView * ) ), + this, SLOT( slotViewCompleted( KonqView * ) ) ); + +#ifndef NDEBUG + dumpViewList(); +#endif + + MapViews::Iterator it = m_mapViews.begin(); + MapViews::Iterator end = m_mapViews.end(); + + // find it in the map - can't use the key since childView->part() might be 0L + + kdDebug(1202) << "Searching map" << endl; + + while ( it != end && it.data() != childView ) + ++it; + + kdDebug(1202) << "Verifying search results" << endl; + + if ( it == m_mapViews.end() ) + { + kdWarning(1202) << "KonqMainWindow::removeChildView childView " << childView << " not in map !" << endl; + return; + } + + kdDebug(1202) << "Removing view " << childView << endl; + + m_mapViews.remove( it ); + + kdDebug(1202) << "View " << childView << " removed from map" << endl; + + viewCountChanged(); + emit viewRemoved( childView ); + +#ifndef NDEBUG + dumpViewList(); +#endif + + // KonqViewManager takes care of m_currentView +} + +void KonqMainWindow::viewCountChanged() +{ + // This is called when the number of views changes. + kdDebug(1202) << "KonqMainWindow::viewCountChanged" << endl; + + int lvc = linkableViewsCount(); + m_paLinkView->setEnabled( lvc > 1 ); + + // Only one view (or one view + sidebar) -> make it/them unlinked + if ( lvc == 1 ) { + MapViews::Iterator it = m_mapViews.begin(); + MapViews::Iterator end = m_mapViews.end(); + for (; it != end; ++it ) + it.data()->setLinkedView( false ); + } + + viewsChanged(); + + m_pViewManager->viewCountChanged(); +} + +void KonqMainWindow::viewsChanged() +{ + // This is called when the number of views changes OR when + // the type of some view changes. + + // Nothing here anymore, but don't cleanup, some might come back later. + + updateViewActions(); // undo, lock, link and other view-dependent actions +} + +KonqView * KonqMainWindow::childView( KParts::ReadOnlyPart *view ) +{ + MapViews::ConstIterator it = m_mapViews.find( view ); + if ( it != m_mapViews.end() ) + return it.data(); + else + return 0L; +} + +KonqView * KonqMainWindow::childView( KParts::ReadOnlyPart *callingPart, const QString &name, KParts::BrowserHostExtension **hostExtension, KParts::ReadOnlyPart **part ) +{ + kdDebug() << "KonqMainWindow::childView this=" << this << " looking for " << name << endl; + + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + { + KonqView* view = it.data(); + QString viewName = view->viewName(); + kdDebug() << " - viewName=" << viewName << " " + << "frame names:" << view->frameNames().join( "," ) << endl; + + // First look for a hostextension containing this frame name + KParts::BrowserHostExtension *ext = KParts::BrowserHostExtension::childObject( view->part() ); + if ( ext ) + { + ext = ext->findFrameParent(callingPart, name); + kdDebug() << "BrowserHostExtension found part " << ext << endl; + if (!ext) + continue; // Don't use this window + } + + if ( !viewName.isEmpty() && viewName == name ) + { + kdDebug() << "found existing view by name: " << view << endl; + if ( hostExtension ) + *hostExtension = 0; + if ( part ) + *part = view->part(); + return view; + } + +// KParts::BrowserHostExtension* ext = KonqView::hostExtension( view->part(), name ); + + if ( ext ) + { + QPtrList<KParts::ReadOnlyPart> frames = ext->frames(); + QPtrListIterator<KParts::ReadOnlyPart> frameIt( frames ); + for ( ; frameIt.current() ; ++frameIt ) + { + if ( frameIt.current()->name() == name ) + { + kdDebug() << "found a frame of name " << name << " : " << frameIt.current() << endl; + if ( hostExtension ) + *hostExtension = ext; + if ( part ) + *part = frameIt.current(); + return view; + } + } + } + } + + return 0; +} + +// static +KonqView * KonqMainWindow::findChildView( KParts::ReadOnlyPart *callingPart, const QString &name, KonqMainWindow **mainWindow, KParts::BrowserHostExtension **hostExtension, KParts::ReadOnlyPart **part ) +{ + if ( !s_lstViews ) + return 0; + + QPtrListIterator<KonqMainWindow> it( *s_lstViews ); + for (; it.current(); ++it ) + { + KonqView *res = it.current()->childView( callingPart, name, hostExtension, part ); + if ( res ) + { + if ( mainWindow ) + *mainWindow = it.current(); + return res; + } + } + + return 0; +} + +int KonqMainWindow::activeViewsCount() const +{ + int res = 0; + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + if ( !it.data()->isPassiveMode() ) + ++res; + + return res; +} + +int KonqMainWindow::linkableViewsCount() const +{ + int res = 0; + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + if ( !it.data()->isFollowActive() ) + ++res; + + return res; +} + +int KonqMainWindow::mainViewsCount() const +{ + int res = 0; + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + if ( !it.data()->isPassiveMode() && !it.data()->isToggleView() ) + { + //kdDebug(1202) << "KonqMainWindow::mainViewsCount " << res << " " << it.data() << " " << it.data()->part()->widget() << endl; + ++res; + } + + return res; +} + +KParts::ReadOnlyPart * KonqMainWindow::currentPart() const +{ + /// ### This is currently unused. Check in the final version (!) if still unused. + if ( m_currentView ) + return m_currentView->part(); + else + return 0L; +} + +void KonqMainWindow::customEvent( QCustomEvent *event ) +{ + KParts::MainWindow::customEvent( event ); + + if ( KonqFileSelectionEvent::test( event ) || + KonqFileMouseOverEvent::test( event ) ) + { + // Forward the event to all views + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + QApplication::sendEvent( (*it)->part(), event ); + return; + } + if ( KParts::OpenURLEvent::test( event ) ) + { + KParts::OpenURLEvent * ev = static_cast<KParts::OpenURLEvent*>(event); + KonqView * senderChildView = childView(ev->part()); + + // Enable/disable local properties actions if current view + if ( senderChildView == m_currentView ) + updateLocalPropsActions(); + + // Forward the event to all views + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + { + // Don't resend to sender + if (it.key() != ev->part()) + { + //kdDebug(1202) << "Sending event to view " << it.key()->className() << endl; + QApplication::sendEvent( it.key(), event ); + + } + } + } +} + +void KonqMainWindow::updateLocalPropsActions() +{ + bool canWrite = false; + if ( m_currentView && m_currentView->url().isLocalFile() ) + { + // Can we write ? + QFileInfo info( m_currentView->url().path() ); + canWrite = info.isDir() && info.isWritable(); + } + m_paSaveViewPropertiesLocally->setEnabled( canWrite ); + m_paRemoveLocalProperties->setEnabled( canWrite ); +} + +void KonqMainWindow::slotURLEntered( const QString &text, int state ) +{ + if ( m_bURLEnterLock || text.isEmpty() ) + return; + + m_bURLEnterLock = true; + + if (state & ControlButton || state & AltButton) + { + m_combo->setURL( m_currentView ? m_currentView->url().prettyURL() : QString::null ); + openFilteredURL( text.stripWhiteSpace(), true ); + } + else + openFilteredURL( text.stripWhiteSpace() ); + + m_bURLEnterLock = false; +} + +void KonqMainWindow::slotFileNewAboutToShow() +{ + // As requested by KNewMenu : + m_pMenuNew->slotCheckUpToDate(); + // And set the files that the menu apply on : + m_pMenuNew->setPopupFiles( KURL( m_currentView->url().url() ) ); +} + +void KonqMainWindow::slotSplitViewHorizontal() +{ + KonqView * newView = m_pViewManager->splitView( Qt::Horizontal ); + if (newView == 0L) return; + newView->openURL( m_currentView->url(), m_currentView->locationBarURL() ); +} + +void KonqMainWindow::slotSplitViewVertical() +{ + KonqView * newView = m_pViewManager->splitView( Qt::Vertical ); + if (newView == 0L) return; + newView->openURL( m_currentView->url(), m_currentView->locationBarURL() ); +} + +void KonqMainWindow::slotAddTab() +{ + KonqView* newView = m_pViewManager->addTab(QString("text/html"), // this is what about:blank will use anyway + QString::null, + false, + KonqSettings::openAfterCurrentPage()); + if (newView == 0L) return; + openURL( newView, KURL("about:blank"),QString::null); + m_pViewManager->showTab( newView ); + focusLocationBar(); + m_pWorkingTab = 0L; +} + +void KonqMainWindow::slotDuplicateTab() +{ + m_pViewManager->duplicateTab( 0, KonqSettings::openAfterCurrentPage() ); +} + +void KonqMainWindow::slotDuplicateTabPopup() +{ + m_pViewManager->duplicateTab( m_pWorkingTab, KonqSettings::openAfterCurrentPage() ); +} + +void KonqMainWindow::slotBreakOffTab() +{ + if (m_currentView && m_currentView->part() && + (m_currentView->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = m_currentView->part()->property("modified"); + if (prop.isValid() && prop.toBool()) + if ( KMessageBox::warningContinueCancel( this, + i18n("This tab contains changes that have not been submitted.\nDetaching the tab will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_breakoff"), "discardchangesdetach") != KMessageBox::Continue ) + return; + } + + m_pViewManager->breakOffTab(); + updateViewActions(); +} + +void KonqMainWindow::slotBreakOffTabPopup() +{ + KonqView* originalView = m_currentView; + KonqView *view = m_pWorkingTab->activeChildView(); + if (view && view->part() && (view->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = view->part()->property("modified"); + if (prop.isValid() && prop.toBool()) { + m_pViewManager->showTab( view ); + if ( KMessageBox::warningContinueCancel( this, + i18n("This tab contains changes that have not been submitted.\nDetaching the tab will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_breakoff"), "discardchangesdetach") != KMessageBox::Continue ) + { + m_pViewManager->showTab( originalView ); + return; + } + } + } + m_pViewManager->showTab( originalView ); + + //Can't do this safely here as the tabbar may disappear and we're + //hanging off here. + QTimer::singleShot(0, this, SLOT( slotBreakOffTabPopupDelayed() ) ); +} + +void KonqMainWindow::slotBreakOffTabPopupDelayed() +{ + m_pViewManager->breakOffTab( m_pWorkingTab ); + updateViewActions(); +} + +void KonqMainWindow::slotPopupNewWindow() +{ + kdDebug(1202) << "KonqMainWindow::slotPopupNewWindow()" << endl; + + KFileItemListIterator it ( popupItems ); + for ( ; it.current(); ++it ) + { + KonqMisc::createNewWindow( (*it)->url(), popupUrlArgs ); + } +} + +void KonqMainWindow::slotPopupThisWindow() +{ + kdDebug(1202) << "KonqMainWindow::slotPopupThisWindow()" << endl; + + openURL( 0L, popupItems.getFirst()->url() ); +} + +void KonqMainWindow::slotPopupNewTab() +{ + bool openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); + bool newTabsInFront = KonqSettings::newTabsInFront(); + + if (KApplication::keyboardMouseState() & Qt::ShiftButton) + newTabsInFront = !newTabsInFront; + + popupNewTab(newTabsInFront, openAfterCurrentPage); +} + +void KonqMainWindow::slotPopupNewTabRight() +{ + bool newTabsInFront = KonqSettings::newTabsInFront(); + + if (KApplication::keyboardMouseState() & ShiftButton) + newTabsInFront = !newTabsInFront; + + popupNewTab(newTabsInFront, false); +} + +void KonqMainWindow::popupNewTab(bool infront, bool openAfterCurrentPage) +{ + kdDebug(1202) << "KonqMainWindow::popupNewTab()" << endl; + + KFileItemListIterator it ( popupItems ); + KonqOpenURLRequest req; + req.newTab = true; + req.newTabInFront = false; + req.openAfterCurrentPage = openAfterCurrentPage; + req.args = popupUrlArgs; + + for ( ; it.current(); ++it ) + { + if ( infront && it.atLast() ) + { + req.newTabInFront = true; + } + openURL( 0L, (*it)->url(), QString::null, req ); + } +} + +void KonqMainWindow::openMultiURL( KURL::List url ) +{ + KURL::List::ConstIterator it = url.begin(); + KURL::List::ConstIterator end = url.end(); + for (; it != end; ++it ) + { + KonqView* newView = m_pViewManager->addTab(); + Q_ASSERT( newView ); + if (newView == 0L) continue; + openURL( newView, *it,QString::null); + m_pViewManager->showTab( newView ); + focusLocationBar(); + m_pWorkingTab = 0L; + } +} + +void KonqMainWindow::slotRemoveView() +{ + if (m_currentView && m_currentView->part() && + (m_currentView->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = m_currentView->part()->property("modified"); + if (prop.isValid() && prop.toBool()) + if ( KMessageBox::warningContinueCancel( this, + i18n("This view contains changes that have not been submitted.\nClosing the view will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"view_remove"), "discardchangesclose") != KMessageBox::Continue ) + return; + } + + // takes care of choosing the new active view + m_pViewManager->removeView( m_currentView ); +} + +void KonqMainWindow::slotRemoveTab() +{ + if (m_currentView && m_currentView->part() && + (m_currentView->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = m_currentView->part()->property("modified"); + if (prop.isValid() && prop.toBool()) + if ( KMessageBox::warningContinueCancel( this, + i18n("This tab contains changes that have not been submitted.\nClosing the tab will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_remove"), "discardchangesclose") != KMessageBox::Continue ) + return; + } + + m_pViewManager->removeTab(); +} + +void KonqMainWindow::slotRemoveTabPopup() +{ + KonqView *originalView = m_currentView; + KonqView *view = m_pWorkingTab->activeChildView(); + if (view && view->part() && (view->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = view->part()->property("modified"); + if (prop.isValid() && prop.toBool()) { + m_pViewManager->showTab( view ); + if ( KMessageBox::warningContinueCancel( this, + i18n("This tab contains changes that have not been submitted.\nClosing the tab will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_remove"), "discardchangesclose") != KMessageBox::Continue ) + { + m_pViewManager->showTab( originalView ); + return; + } + } + m_pViewManager->showTab( originalView ); + } + + //Can't do immediately - may kill the tabbar, and we're in an event path down from it + QTimer::singleShot( 0, this, SLOT( slotRemoveTabPopupDelayed() ) ); +} + +void KonqMainWindow::slotRemoveTabPopupDelayed() +{ + m_pViewManager->removeTab( m_pWorkingTab ); +} + +void KonqMainWindow::slotRemoveOtherTabsPopup() +{ + if ( KMessageBox::warningContinueCancel( this, + i18n("Do you really want to close all other tabs?"), + i18n("Close Other Tabs Confirmation"), KGuiItem(i18n("Close &Other Tabs"),"tab_remove_other"), + "CloseOtherTabConfirm") != KMessageBox::Continue ) + return; + + KonqView *originalView = m_currentView; + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) { + KonqView *view = it.data(); + if ( view != originalView && view && view->part() && (view->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = view->part()->property("modified"); + if (prop.isValid() && prop.toBool()) { + m_pViewManager->showTab( view ); + if ( KMessageBox::warningContinueCancel( this, + i18n("This tab contains changes that have not been submitted.\nClosing other tabs will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_remove"), "discardchangescloseother") != KMessageBox::Continue ) + { + m_pViewManager->showTab( originalView ); + return; + } + } + } + } + m_pViewManager->showTab( originalView ); + + //Can't do immediately - kills the tabbar, and we're in an event path down from it + QTimer::singleShot( 0, this, SLOT( slotRemoveOtherTabsPopupDelayed() ) ); +} + +void KonqMainWindow::slotRemoveOtherTabsPopupDelayed() +{ + m_pViewManager->removeOtherTabs( m_pWorkingTab ); + updateViewActions(); +} + +void KonqMainWindow::slotReloadAllTabs() +{ + KonqView *originalView = m_currentView; + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) { + KonqView *view = it.data(); + if (view && view->part() && (view->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = view->part()->property("modified"); + if (prop.isValid() && prop.toBool()) { + m_pViewManager->showTab( view ); + if ( KMessageBox::warningContinueCancel( this, + i18n("This tab contains changes that have not been submitted.\nReloading all tabs will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"reload"), "discardchangesreload") != KMessageBox::Continue ) + { + m_pViewManager->showTab( originalView ); + return; + } + } + } + } + m_pViewManager->showTab( originalView ); + + m_pViewManager->reloadAllTabs(); + updateViewActions(); +} + + +void KonqMainWindow::slotActivateNextTab() +{ + m_pViewManager->activateNextTab(); +} + +void KonqMainWindow::slotActivatePrevTab() +{ + m_pViewManager->activatePrevTab(); +} + +void KonqMainWindow::slotActivateTab() +{ + m_pViewManager->activateTab( QString( sender()->name() ).right( 2 ).toInt() -1 ); +} + +void KonqMainWindow::slotDumpDebugInfo() +{ +#ifndef NDEBUG + dumpViewList(); + m_pViewManager->printFullHierarchy( 0L ); +#endif +} + +void KonqMainWindow::slotSaveViewPropertiesLocally() +{ + m_bSaveViewPropertiesLocally = !m_bSaveViewPropertiesLocally; + // And this is a main-view setting, so save it + KonqSettings::setSaveViewPropertiesLocally( m_bSaveViewPropertiesLocally ); + KonqSettings::writeConfig(); + // Now tell the views + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + (*it)->callExtensionBoolMethod( "setSaveViewPropertiesLocally(bool)", m_bSaveViewPropertiesLocally ); +} + +void KonqMainWindow::slotRemoveLocalProperties() +{ + assert( m_currentView ); + KURL u ( m_currentView->url() ); + u.addPath(".directory"); + if ( u.isLocalFile() ) + { + QFile f( u.path() ); + if ( f.open(IO_ReadWrite) ) + { + f.close(); + KSimpleConfig config( u.path() ); + config.deleteGroup( "URL properties" ); // Bye bye + config.sync(); + // TODO: Notify the view... + // Or the hard way: (and hoping it doesn't cache the values!) + slotReload(); + } else + { + Q_ASSERT( QFile::exists(u.path()) ); // The action shouldn't be enabled, otherwise. + KMessageBox::sorry( this, i18n("No permissions to write to %1").arg(u.path()) ); + } + } +} + +bool KonqMainWindow::askForTarget(const QString& text, KURL& url) +{ + const KURL initialUrl = (viewCount()==2) ? otherView(m_currentView)->url() : m_currentView->url(); + QString label = text.arg( m_currentView->url().pathOrURL() ); + KURLRequesterDlg dlg(initialUrl.pathOrURL(), label, this, "urlrequester", true); + dlg.setCaption(i18n("Enter Target")); + dlg.urlRequester()->setMode( KFile::File | KFile::ExistingOnly | KFile::Directory ); + if (dlg.exec()) + { + url = dlg.selectedURL(); + if ( url.isValid() ) + return true; + else + { + KMessageBox::error( this, i18n("<qt><b>%1</b> is not valid</qt>").arg(url.url())); + return false; + } + } + return false; +} + +void KonqMainWindow::slotRequesterClicked( KURLRequester *req ) +{ + req->fileDialog()->setMode(KFile::Directory|KFile::ExistingOnly); +} + +void KonqMainWindow::slotCopyFiles() +{ + //kdDebug(1202) << "KonqMainWindow::slotCopyFiles()" << endl; + KURL dest; + if (!askForTarget(i18n("Copy selected files from %1 to:"),dest)) + return; + + KonqOperations::copy(this,KonqOperations::COPY,currentURLs(),dest); +} + +void KonqMainWindow::slotMoveFiles() +{ + //kdDebug(1202) << "KonqMainWindow::slotMoveFiles()" << endl; + KURL dest; + if (!askForTarget(i18n("Move selected files from %1 to:"),dest)) + return; + + KonqOperations::copy(this,KonqOperations::MOVE,currentURLs(),dest); +} + +void KonqMainWindow::slotNewDir() +{ + Q_ASSERT( m_currentView ); + if ( m_currentView ) + KonqOperations::newDir(this, m_currentView->url()); +} + +KURL::List KonqMainWindow::currentURLs() const +{ + KURL::List urls; + if ( m_currentView ) + { + urls.append( m_currentView->url() ); + if ( m_currentView->part()->inherits("KonqDirPart") ) + { + KFileItemList tmpList= static_cast<KonqDirPart *>(m_currentView->part())->selectedFileItems(); + KFileItem *item=tmpList.first(); + if (item) // Return list of selected items only if we have a selection + { + urls.clear(); + for (; item!=0; item=tmpList.next()) + urls.append(item->url()); + } + } + } + return urls; +} + +// Only valid if there are one or two views +KonqView * KonqMainWindow::otherView( KonqView * view ) const +{ + assert( viewCount() <= 2 ); + MapViews::ConstIterator it = m_mapViews.begin(); + if ( (*it) == view ) + ++it; + if ( it != m_mapViews.end() ) + return (*it); + return 0L; +} + +void KonqMainWindow::slotSaveViewProfile() +{ +#if 0 + if ( m_pViewManager->currentProfile().isEmpty() ) + { + // The action should be disabled........... + kdWarning(1202) << "No known profile. Use the Save Profile dialog box" << endl; + } else { + + m_pViewManager->saveViewProfile( m_pViewManager->currentProfile(), + m_pViewManager->currentProfileText(), + false /* URLs */, true /* size */ ); + + } +#endif + m_pViewManager->showProfileDlg( m_pViewManager->currentProfile() ); +} + +void KonqMainWindow::slotUpAboutToShow() +{ + QPopupMenu *popup = m_paUp->popupMenu(); + + popup->clear(); + + uint i = 0; + + // Use the location bar URL, because in case we display a index.html + // we want to go up from the dir, not from the index.html + KURL u( m_currentView->locationBarURL() ); + u = u.upURL(); + while ( u.hasPath() ) + { + popup->insertItem( KonqPixmapProvider::self()->pixmapFor( u.url() ), + u.pathOrURL() ); + + if ( u.path() == "/" ) + break; + + if ( ++i > 10 ) + break; + + u = u.upURL(); + } +} + +void KonqMainWindow::slotUp(KAction::ActivationReason, Qt::ButtonState state) +{ + m_goState = state; + QTimer::singleShot( 0, this, SLOT( slotUpDelayed() ) ); +} + +void KonqMainWindow::slotUp() +{ + m_goState = Qt::LeftButton; + QTimer::singleShot( 0, this, SLOT( slotUpDelayed() ) ); +} + +void KonqMainWindow::slotUpDelayed() +{ + KonqOpenURLRequest req; + req.newTab = true; + + req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); + req.newTabInFront = KonqSettings::newTabsInFront(); + + if (m_goState & Qt::ShiftButton) + req.newTabInFront = !req.newTabInFront; + + const QString& url = m_currentView->upURL().url(); + if(m_goState & Qt::ControlButton) + openFilteredURL(url, req ); + else if(m_goState & Qt::MidButton) + { + if(KonqSettings::mmbOpensTab()) + openFilteredURL( url, req); + else + KonqMisc::createNewWindow( url ); + } + else + openFilteredURL( url, false ); + m_goState = Qt::LeftButton; +} + +void KonqMainWindow::slotUpActivated( int id ) +{ + KURL u( m_currentView->locationBarURL() ); + kdDebug(1202) << "slotUpActivated. Start URL is " << u << endl; + for ( int i = 0 ; i < m_paUp->popupMenu()->indexOf( id ) + 1 ; i ++ ) + u = u.upURL(); + openURL( 0L, u ); +} + +void KonqMainWindow::slotGoMenuAboutToShow() +{ + kdDebug(1202) << "KonqMainWindow::slotGoMenuAboutToShow" << endl; + if ( m_paHistory && m_currentView ) // (maybe this is before initialisation) + m_paHistory->fillGoMenu( m_currentView->history() ); +} + +void KonqMainWindow::slotGoHistoryActivated( int steps ) +{ + slotGoHistoryActivated( steps, Qt::LeftButton ); +} + +void KonqMainWindow::slotGoHistoryActivated( int steps, Qt::ButtonState state ) +{ + kdDebug() <<"slotGoHistoryActivated( "<<steps<<", "<<state<<" )"<<endl; + if (!m_goBuffer) + { + // Only start 1 timer. + m_goBuffer = steps; + m_goState = state; + QTimer::singleShot( 0, this, SLOT(slotGoHistoryDelayed())); + } +} + +void KonqMainWindow::slotGoHistoryDelayed() +{ + if (!m_currentView) return; + + bool openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); + bool mmbOpensTab = KonqSettings::mmbOpensTab(); + bool inFront = KonqSettings::newTabsInFront(); + if(m_goState & Qt::ShiftButton) + inFront = !inFront; + + if(m_goState & Qt::ControlButton) + { + KonqView * newView = m_pViewManager->addTabFromHistory( m_goBuffer, openAfterCurrentPage ); + if (newView && inFront) + m_pViewManager->showTab( newView ); + } + else if(m_goState & Qt::MidButton) + { + if(mmbOpensTab) + { + KonqView * newView = m_pViewManager->addTabFromHistory( m_goBuffer, openAfterCurrentPage ); + if (newView && inFront) + m_pViewManager->showTab( newView ); + } + else + KonqMisc::newWindowFromHistory(this->currentView(), m_goBuffer); + } + else + { + m_currentView->go( m_goBuffer ); + makeViewsFollow(m_currentView->url(), KParts::URLArgs(),m_currentView->serviceType(),m_currentView); + } + + m_goBuffer = 0; + m_goState = Qt::LeftButton; +} + + +void KonqMainWindow::slotBackAboutToShow() +{ + m_paBack->popupMenu()->clear(); + if ( m_currentView ) + KonqBidiHistoryAction::fillHistoryPopup( m_currentView->history(), m_paBack->popupMenu(), true, false ); +} + +void KonqMainWindow::slotBack() +{ + slotGoHistoryActivated(-1); +} + +void KonqMainWindow::slotBack(KAction::ActivationReason, Qt::ButtonState state) +{ + slotGoHistoryActivated( -1, state ); +} + +void KonqMainWindow::slotBackActivated( int id ) +{ + slotGoHistoryActivated( -(m_paBack->popupMenu()->indexOf( id ) + 1), m_paBack->popupMenu()->state()); +} + +void KonqMainWindow::slotForwardAboutToShow() +{ + m_paForward->popupMenu()->clear(); + if ( m_currentView ) + KonqBidiHistoryAction::fillHistoryPopup( m_currentView->history(), m_paForward->popupMenu(), false, true ); +} + +void KonqMainWindow::slotForward() +{ + slotGoHistoryActivated( 1 ); +} + +void KonqMainWindow::slotForward(KAction::ActivationReason, Qt::ButtonState state) +{ + slotGoHistoryActivated( 1, state ); +} + +void KonqMainWindow::slotForwardActivated( int id ) +{ + slotGoHistoryActivated( m_paForward->popupMenu()->indexOf( id ) + 1, m_paForward->popupMenu()->state() ); +} + +void KonqMainWindow::initCombo() +{ + m_combo = new KonqCombo( 0L, "history combo"); + + m_combo->init( s_pCompletion ); + + connect( m_combo, SIGNAL(activated(const QString&,int)), + this, SLOT(slotURLEntered(const QString&,int)) ); + connect( m_combo, SIGNAL(showPageSecurity()), + this, SLOT(showPageSecurity()) ); + + m_pURLCompletion = new KURLCompletion(); + m_pURLCompletion->setCompletionMode( s_pCompletion->completionMode() ); + + // This only turns completion off. ~ is still there in the result + // We do want completion of user names, right? + //m_pURLCompletion->setReplaceHome( false ); // Leave ~ alone! Will be taken care of by filters!! + + connect( m_combo, SIGNAL(completionModeChanged(KGlobalSettings::Completion)), + SLOT( slotCompletionModeChanged( KGlobalSettings::Completion ))); + connect( m_combo, SIGNAL( completion( const QString& )), + SLOT( slotMakeCompletion( const QString& ))); + connect( m_combo, SIGNAL( substringCompletion( const QString& )), + SLOT( slotSubstringcompletion( const QString& ))); + connect( m_combo, SIGNAL( textRotation( KCompletionBase::KeyBindingType) ), + SLOT( slotRotation( KCompletionBase::KeyBindingType ))); + connect( m_combo, SIGNAL( cleared() ), + SLOT ( slotClearHistory() ) ); + connect( m_pURLCompletion, SIGNAL( match(const QString&) ), + SLOT( slotMatch(const QString&) )); + + m_combo->lineEdit()->installEventFilter(this); + + static bool bookmarkCompletionInitialized = false; + if ( !bookmarkCompletionInitialized ) + { + bookmarkCompletionInitialized = true; + DelayedInitializer *initializer = new DelayedInitializer( QEvent::KeyPress, m_combo->lineEdit() ); + connect( initializer, SIGNAL( initialize() ), this, SLOT( bookmarksIntoCompletion() ) ); + } +} + +void KonqMainWindow::bookmarksIntoCompletion() +{ + // add all bookmarks to the completion list for easy access + bookmarksIntoCompletion( KonqBookmarkManager::self()->root() ); +} + +// the user changed the completion mode in the combo +void KonqMainWindow::slotCompletionModeChanged( KGlobalSettings::Completion m ) +{ + s_pCompletion->setCompletionMode( m ); + + KonqSettings::setSettingsCompletionMode( (int)m_combo->completionMode() ); + KonqSettings::writeConfig(); + + // tell the other windows too (only this instance currently) + KonqMainWindow *window = s_lstViews->first(); + while ( window ) { + if ( window->m_combo ) { + window->m_combo->setCompletionMode( m ); + window->m_pURLCompletion->setCompletionMode( m ); + } + window = s_lstViews->next(); + } +} + +// at first, try to find a completion in the current view, then use the global +// completion (history) +void KonqMainWindow::slotMakeCompletion( const QString& text ) +{ + if( m_pURLCompletion ) + { + m_urlCompletionStarted = true; // flag for slotMatch() + + // kdDebug(1202) << "Local Completion object found!" << endl; + QString completion = m_pURLCompletion->makeCompletion( text ); + m_currentDir = QString::null; + + if ( completion.isNull() && !m_pURLCompletion->isRunning() ) + { + // No match() signal will come from m_pURLCompletion + // ask the global one + // tell the static completion object about the current completion mode + completion = s_pCompletion->makeCompletion( text ); + + // some special handling necessary for CompletionPopup + if ( m_combo->completionMode() == KGlobalSettings::CompletionPopup || + m_combo->completionMode() == KGlobalSettings::CompletionPopupAuto ) + m_combo->setCompletedItems( historyPopupCompletionItems( text ) ); + + else if ( !completion.isNull() ) + m_combo->setCompletedText( completion ); + } + else + { + // To be continued in slotMatch()... + if( !m_pURLCompletion->dir().isEmpty() ) + m_currentDir = m_pURLCompletion->dir(); + } + } + // kdDebug(1202) << "Current dir: " << m_currentDir << " Current text: " << text << endl; +} + +void KonqMainWindow::slotSubstringcompletion( const QString& text ) +{ + bool filesFirst = currentURL().startsWith( "/" ) || + currentURL().startsWith( "file:/" ); + QStringList items; + if ( filesFirst && m_pURLCompletion ) + items = m_pURLCompletion->substringCompletion( text ); + + items += s_pCompletion->substringCompletion( text ); + if ( !filesFirst && m_pURLCompletion ) + items += m_pURLCompletion->substringCompletion( text ); + + m_combo->setCompletedItems( items ); +} + +void KonqMainWindow::slotRotation( KCompletionBase::KeyBindingType type ) +{ + // Tell slotMatch() to do nothing + m_urlCompletionStarted = false; + + bool prev = (type == KCompletionBase::PrevCompletionMatch); + if ( prev || type == KCompletionBase::NextCompletionMatch ) { + QString completion = prev ? m_pURLCompletion->previousMatch() : + m_pURLCompletion->nextMatch(); + + if( completion.isNull() ) { // try the history KCompletion object + completion = prev ? s_pCompletion->previousMatch() : + s_pCompletion->nextMatch(); + } + if ( completion.isEmpty() || completion == m_combo->currentText() ) + return; + + m_combo->setCompletedText( completion ); + } +} + +// Handle match() from m_pURLCompletion +void KonqMainWindow::slotMatch( const QString &match ) +{ + if ( match.isEmpty() ) // this case is handled directly + return; + + // Check flag to avoid match() raised by rotation + if ( m_urlCompletionStarted ) { + m_urlCompletionStarted = false; + + // some special handling necessary for CompletionPopup + if ( m_combo->completionMode() == KGlobalSettings::CompletionPopup || + m_combo->completionMode() == KGlobalSettings::CompletionPopupAuto ) { + QStringList items = m_pURLCompletion->allMatches(); + items += historyPopupCompletionItems( m_combo->currentText() ); + // items.sort(); // should we? + m_combo->setCompletedItems( items ); + } + else if ( !match.isNull() ) + m_combo->setCompletedText( match ); + } +} + +void KonqMainWindow::slotCtrlTabPressed() +{ + KonqView * view = m_pViewManager->chooseNextView( m_currentView ); + if ( view ) + m_pViewManager->setActivePart( view->part() ); +} + +void KonqMainWindow::slotClearHistory() +{ + KonqHistoryManager::kself()->emitClear(); +} + +void KonqMainWindow::slotClearComboHistory() +{ + if (m_combo && m_combo->count()) + m_combo->clearHistory(); +} + +bool KonqMainWindow::eventFilter(QObject*obj,QEvent *ev) +{ + if ( ( ev->type()==QEvent::FocusIn || ev->type()==QEvent::FocusOut ) && + m_combo && m_combo->lineEdit() == obj ) + { + //kdDebug(1202) << "KonqMainWindow::eventFilter " << obj << " " << obj->className() << " " << obj->name() << endl; + + QFocusEvent * focusEv = static_cast<QFocusEvent*>(ev); + if (focusEv->reason() == QFocusEvent::Popup) + { + return KParts::MainWindow::eventFilter( obj, ev ); + } + + KParts::BrowserExtension * ext = 0; + if ( m_currentView ) + ext = m_currentView->browserExtension(); + QStrList slotNames; + if (ext) + slotNames = ext->metaObject()->slotNames(); + + //for ( char * s = slotNames.first() ; s ; s = slotNames.next() ) + //{ + // kdDebug(1202) << "slotNames=" << s << endl; + //} + + + if (ev->type()==QEvent::FocusIn) + { + //kdDebug(1202) << "ComboBox got the focus..." << endl; + if (m_bLocationBarConnected) + { + //kdDebug(1202) << "Was already connected..." << endl; + return KParts::MainWindow::eventFilter( obj, ev ); + } + m_bLocationBarConnected = true; + + // Workaround for Qt issue: usually, QLineEdit reacts on Ctrl-D, + // but the duplicate_window action also has Ctrl-D as accel and + // prevents the lineedit from getting this event. IMHO the accel + // should be disabled in favor of the focus-widget. + KAction *duplicate = actionCollection()->action("duplicate_window"); + if ( duplicate->shortcut() == QKeySequence(CTRL+Key_D) ) + duplicate->setEnabled( false ); + + if (slotNames.contains("cut()")) + disconnect( m_paCut, SIGNAL( activated() ), ext, SLOT( cut() ) ); + if (slotNames.contains("copy()")) + disconnect( m_paCopy, SIGNAL( activated() ), ext, SLOT( copy() ) ); + if (slotNames.contains("paste()")) + disconnect( m_paPaste, SIGNAL( activated() ), ext, SLOT( paste() ) ); + if (slotNames.contains("del()")) + disconnect( m_paDelete, SIGNAL( activated() ), ext, SLOT( del() ) ); + disconnect( m_paTrash, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), + this, SLOT( slotTrashActivated( KAction::ActivationReason, Qt::ButtonState ) ) ); + + connect( m_paCut, SIGNAL( activated() ), m_combo->lineEdit(), SLOT( cut() ) ); + connect( m_paCopy, SIGNAL( activated() ), m_combo->lineEdit(), SLOT( copy() ) ); + connect( m_paPaste, SIGNAL( activated() ), m_combo->lineEdit(), SLOT( paste() ) ); + connect( QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged()) ); + connect( m_combo->lineEdit(), SIGNAL(textChanged(const QString &)), this, SLOT(slotCheckComboSelection()) ); + connect( m_combo->lineEdit(), SIGNAL(selectionChanged()), this, SLOT(slotCheckComboSelection()) ); + + m_paTrash->setEnabled(false); + m_paDelete->setEnabled(false); + + slotClipboardDataChanged(); + + } + else if ( ev->type()==QEvent::FocusOut) + { + //kdDebug(1202) << "ComboBox lost focus..." << endl; + if (!m_bLocationBarConnected) + { + //kdDebug(1202) << "Was already disconnected..." << endl; + return KParts::MainWindow::eventFilter( obj, ev ); + } + m_bLocationBarConnected = false; + + // see above in FocusIn for explanation + // we use new_window as reference, as it's always in the same state + // as duplicate_window + KAction *duplicate = actionCollection()->action("duplicate_window"); + if ( duplicate->shortcut() == QKeySequence(CTRL+Key_D) ) + duplicate->setEnabled( actionCollection()->action("new_window")->isEnabled() ); + + if (slotNames.contains("cut()")) + connect( m_paCut, SIGNAL( activated() ), ext, SLOT( cut() ) ); + if (slotNames.contains("copy()")) + connect( m_paCopy, SIGNAL( activated() ), ext, SLOT( copy() ) ); + if (slotNames.contains("paste()")) + connect( m_paPaste, SIGNAL( activated() ), ext, SLOT( paste() ) ); + if (slotNames.contains("del()")) + connect( m_paDelete, SIGNAL( activated() ), ext, SLOT( del() ) ); + connect( m_paTrash, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), + this, SLOT( slotTrashActivated( KAction::ActivationReason, Qt::ButtonState ) ) ); + + disconnect( m_paCut, SIGNAL( activated() ), m_combo->lineEdit(), SLOT( cut() ) ); + disconnect( m_paCopy, SIGNAL( activated() ), m_combo->lineEdit(), SLOT( copy() ) ); + disconnect( m_paPaste, SIGNAL( activated() ), m_combo->lineEdit(), SLOT( paste() ) ); + disconnect( QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged()) ); + disconnect( m_combo->lineEdit(), SIGNAL(textChanged(const QString &)), this, SLOT(slotCheckComboSelection()) ); + disconnect( m_combo->lineEdit(), SIGNAL(selectionChanged()), this, SLOT(slotCheckComboSelection()) ); + + if ( ext ) + { + m_paCut->setEnabled( ext->isActionEnabled( "cut" ) ); + m_paCopy->setEnabled( ext->isActionEnabled( "copy" ) ); + m_paPaste->setEnabled( ext->isActionEnabled( "paste" ) ); + m_paDelete->setEnabled( ext->isActionEnabled( "delete" ) ); + m_paTrash->setEnabled( ext->isActionEnabled( "trash" ) ); + } + else + { + m_paCut->setEnabled( false ); + m_paCopy->setEnabled( false ); + m_paPaste->setEnabled( false ); + m_paDelete->setEnabled( false ); + m_paTrash->setEnabled( false ); + } + } + } + return KParts::MainWindow::eventFilter( obj, ev ); +} + +void KonqMainWindow::slotClipboardDataChanged() +{ + //kdDebug(1202) << "KonqMainWindow::slotClipboardDataChanged()" << endl; + QMimeSource *data = QApplication::clipboard()->data(); + m_paPaste->setEnabled( data->provides( "text/plain" ) ); + slotCheckComboSelection(); +} + +void KonqMainWindow::slotCheckComboSelection() +{ + //kdDebug(1202) << "m_combo->lineEdit()->hasMarkedText() : " << hasSelection << endl; + bool hasSelection = m_combo->lineEdit()->hasSelectedText(); + m_paCopy->setEnabled( hasSelection ); + m_paCut->setEnabled( hasSelection ); +} + +void KonqMainWindow::slotClearLocationBar( KAction::ActivationReason, Qt::ButtonState state ) +{ + kdDebug(1202) << "slotClearLocationBar" << endl; + slotStop(); + m_combo->clearTemporary(); + focusLocationBar(); + if ( state & Qt::MidButton ) + m_combo->setURL( QApplication::clipboard()->text( QClipboard::Selection ) ); +} + +void KonqMainWindow::slotForceSaveMainWindowSettings() +{ +// kdDebug(1202)<<"slotForceSaveMainWindowSettings()"<<endl; + if ( autoSaveSettings() ) // don't do it on e.g. JS window.open windows with no toolbars! + { + saveMainWindowSettings( KGlobal::config(), "KonqMainWindow" ); + KGlobal::config()->sync(); + } +} + +void KonqMainWindow::slotShowMenuBar() +{ + if (menuBar()->isVisible()) + menuBar()->hide(); + else + menuBar()->show(); + slotForceSaveMainWindowSettings(); +} + +void KonqMainWindow::slotUpdateFullScreen( bool set ) +{ + if( set ) + { + showFullScreen(); + // Create toolbar button for exiting from full-screen mode + // ...but only if there isn't one already... + + bool haveFullScreenButton = false; + + //Walk over the toolbars and check whether there is a show fullscreen button in any of them + QPtrListIterator<KToolBar> barIt = toolBarIterator(); + for (; barIt.current(); ++barIt ) + { + //Are we plugged here, in a visible toolbar? + if (barIt.current()->isVisible() && + action( "fullscreen" )->isPlugged(barIt.current())) + { + haveFullScreenButton = true; + break; + } + } + + if (!haveFullScreenButton) + { + QPtrList<KAction> lst; + lst.append( m_ptaFullScreen ); + plugActionList( "fullscreen", lst ); + } + + m_prevMenuBarVisible = menuBar()->isVisible(); + menuBar()->hide(); + m_paShowMenuBar->setChecked( false ); + + // Qt bug, the flags are lost. They know about it. + // happens only with the hackish non-_NET_WM_STATE_FULLSCREEN way + setWFlags( WDestructiveClose ); + // Qt bug (see below) + setAcceptDrops( FALSE ); + topData()->dnd = 0; + setAcceptDrops( TRUE ); + } + else + { +#if QT_VERSION >= 0x030300 + setWindowState( windowState() & ~WindowFullScreen ); +#else + if( isMaximized()) + { + showNormal(); + showMaximized(); // showNormal() would reset maximize state + } + else + showNormal(); +#endif + unplugActionList( "fullscreen" ); + + if (m_prevMenuBarVisible) + { + menuBar()->show(); + m_paShowMenuBar->setChecked( true ); + } + + // Qt bug, the flags aren't restored. They know about it. + setWFlags( WType_TopLevel | WDestructiveClose ); + // Other Qt bug + setAcceptDrops( FALSE ); + topData()->dnd = 0; + setAcceptDrops( TRUE ); + } +} + +void KonqMainWindow::setLocationBarURL( const KURL &url ) +{ + setLocationBarURL( url.pathOrURL() ); +} + +void KonqMainWindow::setLocationBarURL( const QString &url ) +{ + kdDebug(1202) << "KonqMainWindow::setLocationBarURL: url = " << url << endl; + + m_combo->setURL( url ); + + setIcon( KonqPixmapProvider::self()->pixmapFor( url ) ); +} + +void KonqMainWindow::setPageSecurity( PageSecurity pageSecurity ) +{ + m_combo->setPageSecurity( pageSecurity ); +} + +void KonqMainWindow::showPageSecurity() +{ + if ( m_currentView && m_currentView->part() ) { + KAction *act = m_currentView->part()->action( "security" ); + if ( act ) + act->activate(); + } +} + +// called via DCOP from KonquerorIface +void KonqMainWindow::comboAction( int action, const QString& url, const QCString& objId ) +{ + if (!s_lstViews) // this happens in "konqueror --silent" + return; + + KonqCombo *combo = 0L; + KonqMainWindow *window = s_lstViews->first(); + while ( window ) { + if ( window->m_combo ) { + combo = window->m_combo; + + switch ( action ) { + case ComboAdd: + combo->insertPermanent( url ); + break; + case ComboClear: + combo->clearHistory(); + break; + case ComboRemove: + combo->removeURL( url ); + break; + default: + break; + } + } + window = s_lstViews->next(); + } + + // only one instance should save... + if ( combo && objId == kapp->dcopClient()->defaultObject() ) + combo->saveItems(); +} + +QString KonqMainWindow::locationBarURL() const +{ + return m_combo->currentText(); +} + +void KonqMainWindow::focusLocationBar() +{ + if ( m_combo->isVisible() || !isVisible() ) + m_combo->setFocus(); +} + +void KonqMainWindow::startAnimation() +{ + //kdDebug(1202) << "KonqMainWindow::startAnimation" << endl; + m_paAnimatedLogo->start(); + m_paStop->setEnabled( true ); +} + +void KonqMainWindow::stopAnimation() +{ + //kdDebug(1202) << "KonqMainWindow::stopAnimation" << endl; + m_paAnimatedLogo->stop(); + m_paStop->setEnabled( false ); +} + +void KonqMainWindow::setUpEnabled( const KURL &url ) +{ + //kdDebug(1202) << "KonqMainWindow::setUpEnabled(" << url << ")" << endl; + //kdDebug(1202) << "hasPath=" << url.hasPath() << endl; + bool bHasUpURL = false; + + bHasUpURL = ( ( url.hasPath() && url.path() != "/" && ( url.path()[0]=='/' ) ) + || !url.query().isEmpty() /*e.g. lists.kde.org*/ ); + if ( !bHasUpURL ) + bHasUpURL = url.hasSubURL(); + + m_paUp->setEnabled( bHasUpURL ); +} + +void KonqMainWindow::initActions() +{ + actionCollection()->setHighlightingEnabled( true ); + connectActionCollection( actionCollection() ); + + + // Note about this method : don't call setEnabled() on any of the actions. + // They are all disabled then re-enabled with enableAllActions + // If any one needs to be initially disabled, put that code in enableAllActions + + // File menu + m_pMenuNew = new KNewMenu ( actionCollection(), this, "new_menu" ); + QObject::connect( m_pMenuNew->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotFileNewAboutToShow()) ); + + (void) new KAction( i18n( "&Edit File Type..." ), 0, actionCollection(), "editMimeType" ); + (void) new KAction( i18n( "Properties" ), ALT+Key_Return, actionCollection(), "properties" ); + (void) new KAction( i18n( "New &Window" ), "window_new", KStdAccel::shortcut(KStdAccel::New), this, SLOT( slotNewWindow() ), actionCollection(), "new_window" ); + (void) new KAction( i18n( "&Duplicate Window" ), "window_duplicate", CTRL+Key_D, this, SLOT( slotDuplicateWindow() ), actionCollection(), "duplicate_window" ); + (void) new KAction( i18n( "Send &Link Address..." ), "mail_generic", 0, this, SLOT( slotSendURL() ), actionCollection(), "sendURL" ); + (void) new KAction( i18n( "S&end File..." ), "mail_generic", 0, this, SLOT( slotSendFile() ), actionCollection(), "sendPage" ); + if (kapp->authorize("shell_access")) + { + (void) new KAction( i18n( "Open &Terminal" ), "openterm", Key_F4, this, SLOT( slotOpenTerminal() ), actionCollection(), "open_terminal" ); + } + (void) new KAction( i18n( "&Open Location..." ), "fileopen", KStdAccel::shortcut(KStdAccel::Open), this, SLOT( slotOpenLocation() ), actionCollection(), "open_location" ); + + m_paFindFiles = new KToggleAction( i18n( "&Find File..." ), "filefind", KStdAccel::shortcut(KStdAccel::Find), this, SLOT( slotToolFind() ), actionCollection(), "findfile" ); + + m_paPrint = KStdAction::print( 0, 0, actionCollection(), "print" ); + (void) KStdAction::quit( this, SLOT( close() ), actionCollection(), "quit" ); + + m_ptaUseHTML = new KToggleAction( i18n( "&Use index.html" ), 0, this, SLOT( slotShowHTML() ), actionCollection(), "usehtml" ); + m_paLockView = new KToggleAction( i18n( "Lock to Current Location"), 0, this, SLOT( slotLockView() ), actionCollection(), "lock" ); + m_paLinkView = new KToggleAction( i18n( "Lin&k View"), 0, this, SLOT( slotLinkView() ), actionCollection(), "link" ); + + // Go menu + m_paUp = new KToolBarPopupAction( i18n( "&Up" ), "up", KStdAccel::shortcut(KStdAccel::Up), actionCollection(), "up" ); + connect( m_paUp, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, + SLOT( slotUp(KAction::ActivationReason, Qt::ButtonState) ) ); + connect( m_paUp->popupMenu(), SIGNAL( aboutToShow() ), this, SLOT( slotUpAboutToShow() ) ); + connect( m_paUp->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( slotUpActivated( int ) ) ); + + QPair< KGuiItem, KGuiItem > backForward = KStdGuiItem::backAndForward(); + m_paBack = new KToolBarPopupAction( backForward.first, KStdAccel::shortcut(KStdAccel::Back), 0, "", actionCollection(), "back" ); + connect( m_paBack, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, + SLOT( slotBack(KAction::ActivationReason, Qt::ButtonState) ) ); + connect( m_paBack->popupMenu(), SIGNAL( aboutToShow() ), this, SLOT( slotBackAboutToShow() ) ); + connect( m_paBack->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( slotBackActivated( int ) ) ); + + m_paForward = new KToolBarPopupAction( backForward.second, KStdAccel::shortcut(KStdAccel::Forward), 0, "", actionCollection(), "forward" ); + connect( m_paForward, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, + SLOT( slotForward(KAction::ActivationReason, Qt::ButtonState) ) ); + connect( m_paForward->popupMenu(), SIGNAL( aboutToShow() ), this, SLOT( slotForwardAboutToShow() ) ); + connect( m_paForward->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( slotForwardActivated( int ) ) ); + + m_paHistory = new KonqBidiHistoryAction( i18n("History"), actionCollection(), "history" ); + connect( m_paHistory, SIGNAL( menuAboutToShow() ), this, SLOT( slotGoMenuAboutToShow() ) ); + connect( m_paHistory, SIGNAL( activated( int ) ), this, SLOT( slotGoHistoryActivated( int ) ) ); + + m_paHome = new KAction( i18n( "Home" ), "gohome", KStdAccel::shortcut(KStdAccel::Home), actionCollection(), "home" ); + connect( m_paHome, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, + SLOT( slotHome(KAction::ActivationReason, Qt::ButtonState) ) ); + + (void) new KAction( i18n( "S&ystem" ), "system", 0, this, SLOT( slotGoSystem() ), actionCollection(), "go_system" ); + (void) new KAction( i18n( "App&lications" ), "kmenu", 0, this, SLOT( slotGoApplications() ), actionCollection(), "go_applications" ); + (void) new KAction( i18n( "&Storage Media" ), "system", 0, this, SLOT( slotGoMedia() ), actionCollection(), "go_media" ); + (void) new KAction( i18n( "&Network Folders" ), "network", 0, this, SLOT( slotGoNetworkFolders() ), actionCollection(), "go_network_folders" ); + (void) new KAction( i18n( "Sett&ings" ), "kcontrol", 0, this, SLOT( slotGoSettings() ), actionCollection(), "go_settings" ); + //(void) new KAction( i18n( "Sidebar Configuration" ), 0, this, SLOT( slotGoDirTree() ), actionCollection(), "go_dirtree" ); + (void) new KAction( i18n( "Trash" ), "trashcan_full", 0, this, SLOT( slotGoTrash() ), actionCollection(), "go_trash" ); + (void) new KAction( i18n( "Autostart" ), 0, this, SLOT( slotGoAutostart() ), actionCollection(), "go_autostart" ); + KonqMostOftenURLSAction *mostOften = new KonqMostOftenURLSAction( i18n("Most Often Visited"), actionCollection(), "go_most_often" ); + connect( mostOften, SIGNAL( activated( const KURL& )), + SLOT( slotOpenURL( const KURL& ))); + (void) new KAction( i18n( "History" ), "history", 0, this, SLOT( slotGoHistory() ), actionCollection(), "go_history" ); + + // Settings menu + + m_paSaveViewProfile = new KAction( i18n( "&Save View Profile..." ), 0, this, SLOT( slotSaveViewProfile() ), actionCollection(), "saveviewprofile" ); + m_paSaveViewPropertiesLocally = new KToggleAction( i18n( "Save View Changes per &Folder" ), 0, this, SLOT( slotSaveViewPropertiesLocally() ), actionCollection(), "saveViewPropertiesLocally" ); + // "Remove" ? "Reset" ? The former is more correct, the latter is more kcontrol-like... + m_paRemoveLocalProperties = new KAction( i18n( "Remove Folder Properties" ), 0, this, SLOT( slotRemoveLocalProperties() ), actionCollection(), "removeLocalProperties" ); + + + m_configureModules << "kde-filebehavior.desktop" << "kde-fileappearance.desktop" << + "kde-filepreviews.desktop" << "kde-filetypes.desktop" << + "kde-khtml_behavior.desktop" << "kde-khtml_java_js.desktop" << + "kde-khtml_filter.desktop" << + "kde-khtml_fonts.desktop" << "kde-ebrowsing.desktop" << + "kde-kcmhistory.desktop" << "kde-cookies.desktop" << + "kde-cache.desktop" << "kde-proxy.desktop" << "kde-kcmcss.desktop" << + "kde-crypto.desktop" << "kde-useragent.desktop" << + "kde-khtml_plugins.desktop" << "kde-kcmkonqyperformance.desktop"; + + + if (!kapp->authorizeControlModules(configModules()).isEmpty()) + KStdAction::preferences (this, SLOT (slotConfigure()), actionCollection() ); + + KStdAction::keyBindings( guiFactory(), SLOT( configureShortcuts() ), actionCollection() ); + KStdAction::configureToolbars( this, SLOT( slotConfigureToolbars() ), actionCollection() ); + + m_paConfigureExtensions = new KAction( i18n("Configure Extensions..."), 0, this, SLOT( slotConfigureExtensions()), actionCollection(), "options_configure_extensions"); + m_paConfigureSpellChecking = new KAction( i18n("Configure Spell Checking..."), "spellcheck", 0,this, SLOT( slotConfigureSpellChecking()), actionCollection(), "configurespellcheck"); + + // Window menu + m_paSplitViewHor = new KAction( i18n( "Split View &Left/Right" ), "view_left_right", CTRL+SHIFT+Key_L, this, SLOT( slotSplitViewHorizontal() ), actionCollection(), "splitviewh" ); + m_paSplitViewVer = new KAction( i18n( "Split View &Top/Bottom" ), "view_top_bottom", CTRL+SHIFT+Key_T, this, SLOT( slotSplitViewVertical() ), actionCollection(), "splitviewv" ); + m_paAddTab = new KAction( i18n( "&New Tab" ), "tab_new", "CTRL+SHIFT+N;CTRL+T", this, SLOT( slotAddTab() ), actionCollection(), "newtab" ); + m_paDuplicateTab = new KAction( i18n( "&Duplicate Current Tab" ), "tab_duplicate", CTRL+SHIFT+Key_D, this, SLOT( slotDuplicateTab() ), actionCollection(), "duplicatecurrenttab" ); + m_paBreakOffTab = new KAction( i18n( "Detach Current Tab" ), "tab_breakoff", CTRL+SHIFT+Key_B, this, SLOT( slotBreakOffTab() ), actionCollection(), "breakoffcurrenttab" ); + m_paRemoveView = new KAction( i18n( "&Close Active View" ),"view_remove", CTRL+SHIFT+Key_R, this, SLOT( slotRemoveView() ), actionCollection(), "removeview" ); + m_paRemoveTab = new KAction( i18n( "Close Current Tab" ), "tab_remove", CTRL+Key_W, this, SLOT( slotRemoveTab() ), actionCollection(), "removecurrenttab" ); + m_paRemoveOtherTabs = new KAction( i18n( "Close &Other Tabs" ), "tab_remove_other", 0, this, SLOT( slotRemoveOtherTabsPopup() ), actionCollection(), "removeothertabs" ); + + m_paActivateNextTab = new KAction( i18n( "Activate Next Tab" ), "tab_next", QApplication::reverseLayout() ? KStdAccel::tabPrev() : KStdAccel::tabNext(), this, SLOT( slotActivateNextTab() ), actionCollection(), "activatenexttab" ); + m_paActivatePrevTab = new KAction( i18n( "Activate Previous Tab" ), "tab_previous", QApplication::reverseLayout() ? KStdAccel::tabNext() : KStdAccel::tabPrev(), this, SLOT( slotActivatePrevTab() ), actionCollection(), "activateprevtab" ); + + QCString actionname; + for (int i=1;i<13;i++) { + actionname.sprintf("activate_tab_%02d", i); + new KAction(i18n("Activate Tab %1").arg(i), 0, this, SLOT(slotActivateTab()), actionCollection(), actionname); + } + + m_paMoveTabLeft = new KAction( i18n("Move Tab Left"), 0 , CTRL+SHIFT+Key_Left,this, SLOT( slotMoveTabLeft()),actionCollection(),"tab_move_left"); + m_paMoveTabRight = new KAction( i18n("Move Tab Right"), 0 , CTRL+SHIFT+Key_Right,this, SLOT( slotMoveTabRight()),actionCollection(),"tab_move_right"); + +#ifndef NDEBUG + (void) new KAction( i18n( "Dump Debug Info" ), "view_dump_debug_info", 0, this, SLOT( slotDumpDebugInfo() ), actionCollection(), "dumpdebuginfo" ); +#endif + + m_paSaveRemoveViewProfile = new KAction( i18n( "C&onfigure View Profiles..." ), 0, m_pViewManager, SLOT( slotProfileDlg() ), actionCollection(), "saveremoveviewprofile" ); + m_pamLoadViewProfile = new KActionMenu( i18n( "Load &View Profile" ), actionCollection(), "loadviewprofile" ); + + m_pViewManager->setProfiles( m_pamLoadViewProfile ); + + m_ptaFullScreen = KStdAction::fullScreen( 0, 0, actionCollection(), this ); + KShortcut fullScreenShortcut = m_ptaFullScreen->shortcut(); + fullScreenShortcut.append( KKey( Key_F11 ) ); + m_ptaFullScreen->setShortcut( fullScreenShortcut ); + connect( m_ptaFullScreen, SIGNAL( toggled( bool )), this, SLOT( slotUpdateFullScreen( bool ))); + + KShortcut reloadShortcut = KStdAccel::shortcut(KStdAccel::Reload); + reloadShortcut.append(KKey(CTRL + Key_R)); + m_paReload = new KAction( i18n( "&Reload" ), "reload", reloadShortcut, this, SLOT( slotReload() ), actionCollection(), "reload" ); + m_paReloadAllTabs = new KAction( i18n( "&Reload All Tabs" ), "reload_all_tabs", SHIFT+Key_F5, this, SLOT( slotReloadAllTabs() ), actionCollection(), "reload_all_tabs" ); + + m_paUndo = KStdAction::undo( KonqUndoManager::self(), SLOT( undo() ), actionCollection(), "undo" ); + //m_paUndo->setEnabled( KonqUndoManager::self()->undoAvailable() ); + connect( KonqUndoManager::self(), SIGNAL( undoTextChanged( const QString & ) ), + m_paUndo, SLOT( setText( const QString & ) ) ); + + // Those are connected to the browserextension directly + m_paCut = KStdAction::cut( 0, 0, actionCollection(), "cut" ); + KShortcut cutShortCut = m_paCut->shortcut(); + cutShortCut.remove( KKey( SHIFT + Key_Delete ) ); // used for deleting files + m_paCut->setShortcut( cutShortCut ); + + m_paCopy = KStdAction::copy( 0, 0, actionCollection(), "copy" ); + m_paPaste = KStdAction::paste( 0, 0, actionCollection(), "paste" ); + m_paStop = new KAction( i18n( "&Stop" ), "stop", Key_Escape, this, SLOT( slotStop() ), actionCollection(), "stop" ); + + m_paRename = new KAction( i18n( "&Rename" ), /*"editrename",*/ Key_F2, actionCollection(), "rename" ); + m_paTrash = new KAction( i18n( "&Move to Trash" ), "edittrash", Key_Delete, actionCollection(), "trash" ); + connect( m_paTrash, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), + this, SLOT( slotTrashActivated( KAction::ActivationReason, Qt::ButtonState ) ) ); + + m_paDelete = new KAction( i18n( "&Delete" ), "editdelete", SHIFT+Key_Delete, actionCollection(), "del" ); + + m_paAnimatedLogo = new KonqLogoAction( i18n("Animated Logo"), 0, this, SLOT( slotDuplicateWindow() ), actionCollection(), "animated_logo" ); + + // Location bar + m_locationLabel = new KonqDraggableLabel( this, i18n("L&ocation: ") ); + (void) new KWidgetAction( m_locationLabel, i18n("L&ocation: "), Key_F6, this, SLOT( slotLocationLabelActivated() ), actionCollection(), "location_label" ); + m_locationLabel->setBuddy( m_combo ); + + KWidgetAction* comboAction = new KWidgetAction( m_combo, i18n( "Location Bar" ), 0, + 0, 0, actionCollection(), "toolbar_url_combo" ); + comboAction->setShortcutConfigurable( false ); + comboAction->setAutoSized( true ); + + QWhatsThis::add( m_combo, i18n( "Location Bar<p>" + "Enter a web address or search term." ) ); + + KAction *clearLocation = new KAction( i18n( "Clear Location Bar" ), + QApplication::reverseLayout() ? "clear_left" : "locationbar_erase", + CTRL+Key_L, actionCollection(), "clear_location" ); + connect( clearLocation, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), + SLOT( slotClearLocationBar( KAction::ActivationReason, Qt::ButtonState ) ) ); + clearLocation->setWhatsThis( i18n( "Clear Location bar<p>" + "Clears the content of the location bar." ) ); + + // Bookmarks menu + m_pamBookmarks = new KActionMenu( i18n( "&Bookmarks" ), "bookmark", actionCollection(), "bookmarks" ); + m_pamBookmarks->setDelayed( false ); + + // The actual menu needs a different action collection, so that the bookmarks + // don't appear in kedittoolbar + m_bookmarksActionCollection = new KActionCollection( this ); + m_bookmarksActionCollection->setHighlightingEnabled( true ); + connectActionCollection( m_bookmarksActionCollection ); + + m_pBookmarkMenu = new KBookmarkMenu( KonqBookmarkManager::self(), m_pBookmarksOwner, m_pamBookmarks->popupMenu(), m_bookmarksActionCollection, true ); + connect( m_pBookmarkMenu, + SIGNAL( aboutToShowContextMenu(const KBookmark &, QPopupMenu*) ), + this, SLOT( slotFillContextMenu(const KBookmark &, QPopupMenu*) )); + connect( m_pBookmarkMenu, + SIGNAL( openBookmark(const QString &, Qt::ButtonState) ), + this, SLOT( slotOpenBookmarkURL(const QString &, Qt::ButtonState) )); + + KAction *addBookmark = actionCollection()->action("add_bookmark"); + if (addBookmark) + addBookmark->setText(i18n("Bookmark This Location")); + + m_paShowMenuBar = KStdAction::showMenubar( this, SLOT( slotShowMenuBar() ), actionCollection() ); + + (void) new KAction( i18n( "Kon&queror Introduction" ), 0, this, SLOT( slotIntro() ), actionCollection(), "konqintro" ); + + KAction *goUrl = new KAction( i18n( "Go" ), "key_enter", 0, this, SLOT( goURL() ), actionCollection(), "go_url" ); + goUrl->setWhatsThis( i18n( "Go<p>" + "Goes to the page that has been entered into the location bar." ) ); + + enableAllActions( false ); + + // help stuff + m_paUp->setWhatsThis( i18n( "Enter the parent folder<p>" + "For instance, if the current location is file:/home/%1 clicking this " + "button will take you to file:/home." ).arg( KUser().loginName() ) ); + m_paUp->setToolTip( i18n( "Enter the parent folder" ) ); + + m_paBack->setWhatsThis( i18n( "Move backwards one step in the browsing history<p>" ) ); + m_paBack->setToolTip( i18n( "Move backwards one step in the browsing history" ) ); + + m_paForward->setWhatsThis( i18n( "Move forward one step in the browsing history<p>" ) ); + m_paForward->setToolTip( i18n( "Move forward one step in the browsing history" ) ); + + m_paHome->setWhatsThis( i18n( "Navigate to your 'Home Location'<p>" + "You can configure the location this button takes you to in the " + "<b>KDE Control Center</b>, under <b>File Manager</b>/<b>Behavior</b>." ) ); + m_paHome->setToolTip( i18n( "Navigate to your 'Home Location'" ) ); + + m_paReload->setWhatsThis( i18n( "Reload the currently displayed document<p>" + "This may, for example, be needed to refresh webpages that have been " + "modified since they were loaded, in order to make the changes visible." ) ); + m_paReload->setToolTip( i18n( "Reload the currently displayed document" ) ); + + m_paReloadAllTabs->setWhatsThis( i18n( "Reload all currently displayed documents in tabs<p>" + "This may, for example, be needed to refresh webpages that have been " + "modified since they were loaded, in order to make the changes visible." ) ); + m_paReloadAllTabs->setToolTip( i18n( "Reload all currently displayed document in tabs" ) ); + + m_paStop->setWhatsThis( i18n( "Stop loading the document<p>" + "All network transfers will be stopped and Konqueror will display the content " + "that has been received so far." ) ); + m_paStop->setToolTip( i18n( "Stop loading the document" ) ); + + m_paCut->setWhatsThis( i18n( "Cut the currently selected text or item(s) and move it " + "to the system clipboard<p> " + "This makes it available to the <b>Paste</b> command in Konqueror " + "and other KDE applications." ) ); + m_paCut->setToolTip( i18n( "Move the selected text or item(s) to the clipboard" ) ); + + m_paCopy->setWhatsThis( i18n( "Copy the currently selected text or item(s) to the " + "system clipboard<p>" + "This makes it available to the <b>Paste</b> command in Konqueror " + "and other KDE applications." ) ); + m_paCopy->setToolTip( i18n( "Copy the selected text or item(s) to the clipboard" ) ); + + m_paPaste->setWhatsThis( i18n( "Paste the previously cut or copied clipboard " + "contents<p>" + "This also works for text copied or cut from other KDE applications." ) ); + m_paPaste->setToolTip( i18n( "Paste the clipboard contents" ) ); + + m_paPrint->setWhatsThis( i18n( "Print the currently displayed document<p>" + "You will be presented with a dialog where you can set various " + "options, such as the number of copies to print and which printer " + "to use.<p>" + "This dialog also provides access to special KDE printing " + "services such as creating a PDF file from the current document." ) ); + m_paPrint->setToolTip( i18n( "Print the current document" ) ); + + + + // Please proof-read those (David) + + m_ptaUseHTML->setToolTip( i18n("If present, open index.html when entering a folder.") ); + m_paLockView->setToolTip( i18n("A locked view cannot change folders. Use in combination with 'link view' to explore many files from one folder") ); + m_paLinkView->setToolTip( i18n("Sets the view as 'linked'. A linked view follows folder changes made in other linked views.") ); +} + +void KonqMainWindow::slotFillContextMenu( const KBookmark &bk, QPopupMenu * pm ) +{ + kdDebug() << "KonqMainWindow::slotFillContextMenu(bk, pm == " << pm << ")" << endl; + popupItems.clear(); + popupUrlArgs = KParts::URLArgs(); + + //Set tab_new_x to point to the correct icon based on NewTabsInFront + bool newtabsinfront = KonqSettings::newTabsInFront(); + QString tab_new_x ; + if ( newtabsinfront ) + tab_new_x = "tab_new" ; + else + tab_new_x = "tab_new_bg" ; + + if ( bk.isGroup() ) + { + KBookmarkGroup grp = bk.toGroup(); + QValueList<KURL> list = grp.groupUrlList(); + QValueList<KURL>::Iterator it = list.begin(); + for (; it != list.end(); ++it ) + popupItems.append( new KFileItem( (*it), QString::null, KFileItem::Unknown) ); + pm->insertItem( SmallIcon(tab_new_x), i18n( "Open Folder in Tabs" ), this, SLOT( slotPopupNewTabRight() ) ); + } + else + { + popupItems.append( new KFileItem( bk.url(), QString::null, KFileItem::Unknown) ); + pm->insertItem( SmallIcon("window_new"), i18n( "Open in New Window" ), this, SLOT( slotPopupNewWindow() ) ); + pm->insertItem( SmallIcon(tab_new_x), i18n( "Open in New Tab" ), this, SLOT( slotPopupNewTabRight() ) ); + } +} + +void KonqMainWindow::slotOpenBookmarkURL( const QString & url, Qt::ButtonState state) +{ + kdDebug(1202) << "KonqMainWindow::slotOpenBookmarkURL(" << url << ", " << state << ")" << endl; + + KonqOpenURLRequest req; + req.newTab = true; + req.newTabInFront = KonqSettings::newTabsInFront(); + + if (state & Qt::ShiftButton) + req.newTabInFront = !req.newTabInFront; + + if( state & Qt::ControlButton ) // Ctrl Left/MMB + openFilteredURL( url, req); + else if( state & Qt::MidButton ) + { + if(KonqSettings::mmbOpensTab()) + openFilteredURL( url, req); + else + { + KURL finalURL = KonqMisc::konqFilteredURL( this, url ); + KonqMisc::createNewWindow( finalURL.url() ); + } + } + else + openFilteredURL( url, false ); +} + +void KonqMainWindow::slotMoveTabLeft() +{ + if ( QApplication::reverseLayout() ) + m_pViewManager->moveTabForward(); + else + m_pViewManager->moveTabBackward(); +} + +void KonqMainWindow::slotMoveTabRight() +{ + if ( QApplication::reverseLayout() ) + m_pViewManager->moveTabBackward(); + else + m_pViewManager->moveTabForward(); +} + +void KonqMainWindow::updateToolBarActions( bool pendingAction /*=false*/) +{ + // Enables/disables actions that depend on the current view & url (mostly toolbar) + // Up, back, forward, the edit extension, stop button, wheel + setUpEnabled( m_currentView->url() ); + m_paBack->setEnabled( m_currentView->canGoBack() ); + m_paForward->setEnabled( m_currentView->canGoForward() ); + + if ( m_currentView->isLoading() ) + { + startAnimation(); // takes care of m_paStop + } + else + { + m_paAnimatedLogo->stop(); + m_paStop->setEnabled( pendingAction ); //enable/disable based on any pending actions... + } + + if ( m_currentView && m_currentView->url().isLocalFile() && + !m_currentView->isLockedViewMode() ) { + if ( m_currentView->serviceTypes().contains( "inode/directory" ) ) + m_ptaUseHTML->setEnabled( true ); + else if ( m_currentView->serviceTypes().contains( "text/html" ) ) { + // Currently viewing an index.html file via this feature (i.e. url points to a dir) + QString locPath = KURL( m_currentView->locationBarURL() ).path(); + m_ptaUseHTML->setEnabled( QFileInfo( locPath ).isDir() ); + } else + m_ptaUseHTML->setEnabled( false ); + } + else + { + m_ptaUseHTML->setEnabled( false ); + } +} + +void KonqMainWindow::updateViewActions() +{ + // Update actions that depend on the current view and its mode, or on the number of views etc. + + // Don't do things in this method that depend on m_currentView->url(). + // When going 'back' in history this will be called before opening the url. + // Use updateToolBarActions instead. + + slotUndoAvailable( KonqUndoManager::self()->undoAvailable() ); + + // Can lock a view only if there is a next view + //m_paLockView->setEnabled( m_pViewManager->chooseNextView(m_currentView) != 0L && ); + //kdDebug(1202) << "KonqMainWindow::updateViewActions m_paLockView enabled ? " << m_paLockView->isEnabled() << endl; + + m_paLockView->setEnabled( viewCount() > 1 ); + m_paLockView->setChecked( m_currentView && m_currentView->isLockedLocation() ); + + // Can remove view if we'll still have a main view after that + m_paRemoveView->setEnabled( mainViewsCount() > 1 || + ( m_currentView && m_currentView->isToggleView() ) ); + + KonqFrameBase* docContainer = m_pViewManager->docContainer(); + + if ( docContainer == 0L && !(currentView() && currentView()->frame())) + { + m_paAddTab->setEnabled( false ); + m_paDuplicateTab->setEnabled( false ); + m_paRemoveTab->setEnabled( false ); + m_paRemoveOtherTabs->setEnabled( false ); + m_paBreakOffTab->setEnabled( false ); + m_paActivateNextTab->setEnabled( false ); + m_paActivatePrevTab->setEnabled( false ); + m_paMoveTabLeft->setEnabled( false ); + m_paMoveTabRight->setEnabled( false ); + } + else + { + m_paAddTab->setEnabled( true ); + m_paDuplicateTab->setEnabled( true ); + if ( docContainer && docContainer->frameType() == "Tabs" ) + { + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(docContainer); + bool state = (tabContainer->count()>1); + m_paRemoveTab->setEnabled( state ); + m_paRemoveOtherTabs->setEnabled( state ); + m_paBreakOffTab->setEnabled( state ); + m_paActivateNextTab->setEnabled( state ); + m_paActivatePrevTab->setEnabled( state ); + + QPtrList<KonqFrameBase>* childFrameList = tabContainer->childFrameList(); + m_paMoveTabLeft->setEnabled( currentView() ? currentView()->frame()!= + (QApplication::reverseLayout() ? childFrameList->last() : childFrameList->first()) : false ); + m_paMoveTabRight->setEnabled( currentView() ? currentView()->frame()!= + (QApplication::reverseLayout() ? childFrameList->first() : childFrameList->last()) : false ); + } + else + { + m_paRemoveTab->setEnabled( false ); + m_paRemoveOtherTabs->setEnabled( false ); + m_paBreakOffTab->setEnabled( false ); + m_paActivateNextTab->setEnabled( false ); + m_paActivatePrevTab->setEnabled( false ); + m_paMoveTabLeft->setEnabled( false ); + m_paMoveTabRight->setEnabled( false ); + + } + } + + // Can split a view if it's not a toggle view (because a toggle view can be here only once) + bool isNotToggle = m_currentView && !m_currentView->isToggleView(); + m_paSplitViewHor->setEnabled( isNotToggle ); + m_paSplitViewVer->setEnabled( isNotToggle ); + + m_paLinkView->setChecked( m_currentView && m_currentView->isLinkedView() ); + + if ( m_currentView && m_currentView->part() && + m_currentView->part()->inherits("KonqDirPart") ) + { + KonqDirPart * dirPart = static_cast<KonqDirPart *>(m_currentView->part()); + m_paFindFiles->setEnabled( dirPart->findPart() == 0 ); + + // Create the copy/move options if not already done + if ( !m_paCopyFiles ) + { + // F5 is the default key binding for Reload.... a la Windows. + // mc users want F5 for Copy and F6 for move, but I can't make that default. + m_paCopyFiles = new KAction( i18n("Copy &Files..."), Key_F7, this, SLOT( slotCopyFiles() ), actionCollection(), "copyfiles" ); + m_paMoveFiles = new KAction( i18n("M&ove Files..."), Key_F8, this, SLOT( slotMoveFiles() ), actionCollection(), "movefiles" ); + + // This action doesn't appear in the GUI, it's for the shortcut only. + // KNewMenu takes care of the GUI stuff. + m_paNewDir = new KAction( i18n("Create Folder..." ), Key_F10, this, SLOT( slotNewDir() ), + actionCollection(), "konq_create_dir" ); + + QPtrList<KAction> lst; + lst.append( m_paCopyFiles ); + lst.append( m_paMoveFiles ); + m_paCopyFiles->setEnabled( false ); + m_paMoveFiles->setEnabled( false ); + plugActionList( "operations", lst ); + } + } + else + { + m_paFindFiles->setEnabled( false ); + + if (m_paCopyFiles) + { + unplugActionList( "operations" ); + delete m_paCopyFiles; + m_paCopyFiles = 0; + delete m_paMoveFiles; + m_paMoveFiles = 0; + delete m_paNewDir; + m_paNewDir = 0; + } + } +} + +QString KonqMainWindow::findIndexFile( const QString &dir ) +{ + QDir d( dir ); + + QString f = d.filePath( "index.html", false ); + if ( QFile::exists( f ) ) + return f; + + f = d.filePath( "index.htm", false ); + if ( QFile::exists( f ) ) + return f; + + f = d.filePath( "index.HTML", false ); + if ( QFile::exists( f ) ) + return f; + + return QString::null; +} + +void KonqMainWindow::connectExtension( KParts::BrowserExtension *ext ) +{ + //kdDebug(1202) << "Connecting extension " << ext << endl; + KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); + KParts::BrowserExtension::ActionSlotMap::ConstIterator it = actionSlotMap->begin(); + KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd = actionSlotMap->end(); + + QStrList slotNames = ext->metaObject()->slotNames(); + + for ( ; it != itEnd ; ++it ) + { + KAction * act = actionCollection()->action( it.key() ); + //kdDebug(1202) << it.key() << endl; + if ( act ) + { + // Does the extension have a slot with the name of this action ? + if ( slotNames.contains( it.key()+"()" ) ) + { + if ( it.key() != "trash" ) + connect( act, SIGNAL( activated() ), ext, it.data() /* SLOT(slot name) */ ); + act->setEnabled( ext->isActionEnabled( it.key() ) ); + const QString text = ext->actionText( it.key() ); + if ( !text.isEmpty() ) + act->setText( text ); + // TODO how to re-set the original action text, when switching to a part that didn't call setAction? + // Can't test with Paste... + } else + act->setEnabled(false); + + } else kdError(1202) << "Error in BrowserExtension::actionSlotMap(), unknown action : " << it.key() << endl; + } + +} + +void KonqMainWindow::disconnectExtension( KParts::BrowserExtension *ext ) +{ + //kdDebug(1202) << "Disconnecting extension " << ext << endl; + KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); + KParts::BrowserExtension::ActionSlotMap::ConstIterator it = actionSlotMap->begin(); + KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd = actionSlotMap->end(); + + QStrList slotNames = ext->metaObject()->slotNames(); + + for ( ; it != itEnd ; ++it ) + { + KAction * act = actionCollection()->action( it.key() ); + //kdDebug(1202) << it.key() << endl; + if ( act && slotNames.contains( it.key()+"()" ) ) + { + //kdDebug(1202) << "disconnectExtension: " << act << " " << act->name() << endl; + act->disconnect( ext ); + } + } +} + +void KonqMainWindow::slotTrashActivated( KAction::ActivationReason reason, Qt::ButtonState state ) +{ + if ( !m_currentView ) + return; + if ( reason == KAction::PopupMenuActivation && ( state & Qt::ShiftButton ) ) + m_currentView->callExtensionMethod( "del()" ); + else + m_currentView->callExtensionMethod( "trash()" ); +} + +void KonqMainWindow::enableAction( const char * name, bool enabled ) +{ + KAction * act = actionCollection()->action( name ); + if (!act) + kdWarning(1202) << "Unknown action " << name << " - can't enable" << endl; + else + { + if ( m_bLocationBarConnected && ( + act==m_paCopy || act==m_paCut || act==m_paPaste || act==m_paDelete || act==m_paTrash ) ) + // Don't change action state while the location bar has focus. + return; + //kdDebug(1202) << "KonqMainWindow::enableAction " << name << " " << enabled << endl; + act->setEnabled( enabled ); + } + + // Update "copy files" and "move files" accordingly + if (m_paCopyFiles && !strcmp( name, "copy" )) + { + m_paCopyFiles->setEnabled( enabled ); + } + else if (m_paMoveFiles && !strcmp( name, "cut" )) + { + m_paMoveFiles->setEnabled( enabled ); + } +} + +void KonqMainWindow::setActionText( const char * name, const QString& text ) +{ + KAction * act = actionCollection()->action( name ); + if (!act) + kdWarning(1202) << "Unknown action " << name << " - can't enable" << endl; + else + { + kdDebug(1202) << "KonqMainWindow::setActionText " << name << " " << text << endl; + act->setText( text ); + } +} + +void KonqMainWindow::currentProfileChanged() +{ + bool enabled = !m_pViewManager->currentProfile().isEmpty(); + m_paSaveViewProfile->setEnabled( enabled ); + m_paSaveViewProfile->setText( enabled ? i18n("&Save View Profile \"%1\"...").arg(m_pViewManager->currentProfileText()) + : i18n("&Save View Profile...") ); +} + +void KonqMainWindow::enableAllActions( bool enable ) +{ + kdDebug(1202) << "KonqMainWindow::enableAllActions " << enable << endl; + KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); + + QValueList<KAction *> actions = actionCollection()->actions(); + QValueList<KAction *>::Iterator it = actions.begin(); + QValueList<KAction *>::Iterator end = actions.end(); + for (; it != end; ++it ) + { + KAction *act = *it; + if ( !QString(act->name()).startsWith("options_configure") /* do not touch the configureblah actions */ + && ( !enable || !actionSlotMap->contains( act->name() ) ) ) /* don't enable BE actions */ + act->setEnabled( enable ); + } + // This method is called with enable=false on startup, and + // then only once with enable=true when the first view is setup. + // So the code below is where actions that should initially be disabled are disabled. + if (enable) + { + setUpEnabled( m_currentView ? m_currentView->url() : KURL() ); + // we surely don't have any history buffers at this time + m_paBack->setEnabled( false ); + m_paForward->setEnabled( false ); + + // Load profile submenu + m_pViewManager->profileListDirty( false ); + + currentProfileChanged(); + + updateViewActions(); // undo, lock, link and other view-dependent actions + + m_paStop->setEnabled( m_currentView && m_currentView->isLoading() ); + + if (m_toggleViewGUIClient) + { + QPtrList<KAction> actions = m_toggleViewGUIClient->actions(); + for ( KAction * it = actions.first(); it ; it = actions.next() ) + it->setEnabled( true ); + } + + } + actionCollection()->action( "quit" )->setEnabled( true ); +} + +void KonqMainWindow::disableActionsNoView() +{ + // No view -> there are some things we can't do + m_paUp->setEnabled( false ); + m_paReload->setEnabled( false ); + m_paReloadAllTabs->setEnabled( false ); + m_paBack->setEnabled( false ); + m_paForward->setEnabled( false ); + m_ptaUseHTML->setEnabled( false ); + m_pMenuNew->setEnabled( false ); + m_paLockView->setEnabled( false ); + m_paLockView->setChecked( false ); + m_paSplitViewVer->setEnabled( false ); + m_paSplitViewHor->setEnabled( false ); + m_paRemoveView->setEnabled( false ); + m_paLinkView->setEnabled( false ); + if (m_toggleViewGUIClient) + { + QPtrList<KAction> actions = m_toggleViewGUIClient->actions(); + for ( KAction * it = actions.first(); it ; it = actions.next() ) + it->setEnabled( false ); + } + // There are things we can do, though : bookmarks, view profile, location bar, new window, + // settings, etc. + m_paHome->setEnabled( true ); + m_pamBookmarks->setEnabled( true ); + static const char* const s_enActions[] = { "new_window", "duplicate_window", "open_location", + "toolbar_url_combo", "clear_location", "animated_logo", + "konqintro", "go_most_often", "go_applications", "go_dirtree", + "go_trash", "go_settings", "go_network_folders", "go_autostart", + "go_url", "go_media", "go_history", "options_configure_extensions", 0 }; + for ( int i = 0 ; s_enActions[i] ; ++i ) + { + KAction * act = action(s_enActions[i]); + if (act) + act->setEnabled( true ); + } + m_pamLoadViewProfile->setEnabled( true ); + m_paSaveViewProfile->setEnabled( true ); + m_paSaveRemoveViewProfile->setEnabled( true ); + m_combo->clearTemporary(); + updateLocalPropsActions(); +} + +void KonqExtendedBookmarkOwner::openBookmarkURL( const QString & /*url*/ ) +{ + // Do nothing, we catch the signal +} + +void KonqMainWindow::setCaption( const QString &caption ) +{ + // KParts sends us empty captions when activating a brand new part + // We can't change it there (in case of apps removing all parts altogether) + // but here we never do that. + if ( !caption.isEmpty() && m_currentView ) + { + kdDebug(1202) << "KonqMainWindow::setCaption(" << caption << ")" << endl; + + // Keep an unmodified copy of the caption (before kapp->makeStdCaption is applied) + m_currentView->setCaption( caption ); + KParts::MainWindow::setCaption( m_currentView->caption() ); + } +} + +void KonqMainWindow::show() +{ + // We need to check if our toolbars are shown/hidden here, and set + // our menu items accordingly. We can't do it in the constructor because + // view profiles store toolbar info, and that info is read after + // construct time. + m_paShowMenuBar->setChecked( !menuBar()->isHidden() ); + updateBookmarkBar(); // hide if empty + + // Call parent method + KParts::MainWindow::show(); +} + +QString KonqExtendedBookmarkOwner::currentURL() const +{ + return m_pKonqMainWindow->currentURL(); +} + +QString KonqMainWindow::currentProfile() const +{ + return m_pViewManager->currentProfile(); +} + +QString KonqMainWindow::currentURL() const +{ + if ( !m_currentView ) + return QString::null; + QString url = m_currentView->url().prettyURL(); + if ( m_currentView->part() && m_currentView->part()->inherits("KonqDirPart") ) + { + QString nameFilter = static_cast<KonqDirPart *>(m_currentView->part())->nameFilter(); + if ( !nameFilter.isEmpty() ) + { + if (!url.endsWith("/")) + url += '/'; + url += nameFilter; + } + } + return url; +} + +void KonqExtendedBookmarkOwner::slotFillBookmarksList( KExtendedBookmarkOwner::QStringPairList & list ) +{ + KonqFrameBase *docContainer = m_pKonqMainWindow->viewManager()->docContainer(); + if (docContainer == 0L) return; + if (docContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(docContainer); + + QPtrList<KonqFrameBase> frameList = *tabContainer->childFrameList(); + QPtrListIterator<KonqFrameBase> it( frameList ); + + for ( it.toFirst(); it != 0L; ++it ) + { + if ( !it.current()->activeChildView() ) + continue; + if( it.current()->activeChildView()->locationBarURL().isEmpty() ) + continue; + list << qMakePair( it.current()->activeChildView()->caption(), + it.current()->activeChildView()->url().url() ); + } +} + +QString KonqExtendedBookmarkOwner::currentTitle() const +{ + return m_pKonqMainWindow->currentTitle(); +} + +QString KonqMainWindow::currentTitle() const +{ + return m_currentView ? m_currentView->caption() : QString::null; +} + +void KonqMainWindow::slotPopupMenu( const QPoint &_global, const KURL &url, const QString &_mimeType, mode_t _mode ) +{ + slotPopupMenu( 0L, _global, url, _mimeType, _mode ); +} + +void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KURL &url, const QString &_mimeType, mode_t _mode ) +{ + KFileItem item( url, _mimeType, _mode ); + KFileItemList items; + items.append( &item ); + slotPopupMenu( client, _global, items, KParts::URLArgs(), KParts::BrowserExtension::DefaultPopupItems, false ); //BE CAREFUL WITH sender() ! +} + +void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KURL &url, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags f, mode_t _mode ) +{ + KFileItem item( url, _args.serviceType, _mode ); + KFileItemList items; + items.append( &item ); + slotPopupMenu( client, _global, items, _args, f, false ); //BE CAREFUL WITH sender() ! +} + +void KonqMainWindow::slotPopupMenu( const QPoint &_global, const KFileItemList &_items ) +{ + slotPopupMenu( 0L, _global, _items ); +} + +void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KFileItemList &_items ) +{ + slotPopupMenu( client, _global, _items, KParts::URLArgs(), KParts::BrowserExtension::DefaultPopupItems, true ); +} + +void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KFileItemList &_items, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags _flags ) +{ + slotPopupMenu( client, _global, _items, _args, _flags, true ); +} + +void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KFileItemList &_items, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags itemFlags, bool showProperties ) +{ + KonqView * m_oldView = m_currentView; + + KonqView * currentView = childView( static_cast<KParts::ReadOnlyPart *>( sender()->parent() ) ); + + //kdDebug() << "KonqMainWindow::slotPopupMenu m_oldView=" << m_oldView << " new currentView=" << currentView << " passive:" << currentView->isPassiveMode() << endl; + + if ( (m_oldView != currentView) && currentView->isPassiveMode() ) + { + // Make this view active only temporarily (because it's passive) + m_currentView = currentView; + + if ( m_oldView && m_oldView->browserExtension() ) + disconnectExtension( m_oldView->browserExtension() ); + if ( m_currentView->browserExtension() ) + connectExtension( m_currentView->browserExtension() ); + } + // Note that if m_oldView!=currentView and currentView isn't passive, + // then the KParts mechanism has already noticed the click in it, + // but KonqViewManager delays the GUI-rebuilding with a single-shot timer. + // Right after the popup shows up, currentView _will_ be m_currentView. + + //kdDebug(1202) << "KonqMainWindow::slotPopupMenu( " << client << "...)" << " current view=" << m_currentView << " " << m_currentView->part()->className() << endl; + + // This action collection is used to pass actions to KonqPopupMenu. + // It has to be a KActionCollection instead of a KActionPtrList because we need + // the actionStatusText signal... + KActionCollection popupMenuCollection( (QWidget*)0 ); + popupMenuCollection.insert( m_paBack ); + popupMenuCollection.insert( m_paForward ); + popupMenuCollection.insert( m_paUp ); + popupMenuCollection.insert( m_paReload ); + + popupMenuCollection.insert( m_paFindFiles ); + + popupMenuCollection.insert( m_paUndo ); + popupMenuCollection.insert( m_paCut ); + popupMenuCollection.insert( m_paCopy ); + popupMenuCollection.insert( m_paPaste ); + popupMenuCollection.insert( m_paTrash ); + popupMenuCollection.insert( m_paRename ); + popupMenuCollection.insert( m_paDelete ); + + // The pasteto action is used when clicking on a dir, to paste into it. + KAction *actPaste = KStdAction::paste( this, SLOT( slotPopupPasteTo() ), &popupMenuCollection, "pasteto" ); + actPaste->setEnabled( m_paPaste->isEnabled() ); + popupMenuCollection.insert( actPaste ); + + bool sReading = false; + if ( _items.count() > 0 ) + { + m_popupURL = _items.getFirst()->url(); + sReading = KProtocolInfo::supportsReading( m_popupURL ); + if (sReading) + m_popupServiceType = _items.getFirst()->mimetype(); + } + else + { + m_popupURL = KURL(); + m_popupServiceType = QString::null; + } + + if ( (_items.count() == 1) && !m_popupServiceType.isEmpty() ) { + QString currentServiceName = currentView->service()->desktopEntryName(); + + // List of services for the "Preview In" submenu. + m_popupEmbeddingServices = KTrader::self()->query( + m_popupServiceType, + "KParts/ReadOnlyPart", + // Obey "HideFromMenus". It defaults to false so we want "absent or true" + // (wow, testing for 'true' if absent doesn't work, so order matters) + "(not exist [X-KDE-BrowserView-HideFromMenus] or not [X-KDE-BrowserView-HideFromMenus]) " + "and DesktopEntryName != '"+currentServiceName+"' " + // I had an old local dirtree.desktop without lib, no need for invalid entries + "and exist [Library]", + QString::null ); + } + + + // Don't set the view URL for a toggle view. + // (This is a bit of a hack for the directory tree....) + // ## should use the new currentView->isHierarchicalView() instead? + // Would this be correct for the konqlistview tree view? + KURL viewURL = currentView->isToggleView() ? KURL() : currentView->url(); + + bool openedForViewURL = false; + //bool dirsSelected = false; + bool devicesFile = false; + + if ( _items.count() == 1 ) + { + KURL firstURL = _items.getFirst()->url(); + if ( !viewURL.isEmpty() ) + { + //firstURL.cleanPath(); + openedForViewURL = firstURL.equals( viewURL, true ); + } + devicesFile = firstURL.protocol().find("device", 0, false) == 0; + //dirsSelected = S_ISDIR( _items.getFirst()->mode() ); + } + //check if current url is trash + KURL url = viewURL; + url.cleanPath(); + bool isIntoTrash = url.protocol() == "trash" || url.url().startsWith( "system:/trash" ); + bool doTabHandling = !openedForViewURL && !isIntoTrash && sReading; + bool showEmbeddingServices = !isIntoTrash && !devicesFile && (itemFlags & KParts::BrowserExtension::ShowTextSelectionItems) == 0; + PopupMenuGUIClient *konqyMenuClient = new PopupMenuGUIClient( this, m_popupEmbeddingServices, + showEmbeddingServices, doTabHandling ); + + //kdDebug(1202) << "KonqMainWindow::slotPopupMenu " << viewURL.prettyURL() << endl; + + + // Those actions go into the PopupMenuGUIClient, since that's the one defining them. + KAction *actNewWindow = 0L, *actNewTab = 0L; + if( doTabHandling ) + { + if (_args.forcesNewWindow()) { + actNewWindow = new KAction( i18n( "Open in T&his Window" ), 0, this, SLOT( slotPopupThisWindow() ), konqyMenuClient->actionCollection(), "sameview" ); + actNewWindow->setToolTip( i18n( "Open the document in current window" ) ); + } + actNewWindow = new KAction( i18n( "Open in New &Window" ), "window_new", 0, this, SLOT( slotPopupNewWindow() ), konqyMenuClient->actionCollection(), "newview" ); + actNewWindow->setToolTip( i18n( "Open the document in a new window" ) ); + + //Set tab_new_x to point to the correct icon based on NewTabsInFront + bool newtabsinfront = KonqSettings::newTabsInFront(); + QString tab_new_x ; + if ( newtabsinfront ) + tab_new_x = "tab_new" ; + else + tab_new_x = "tab_new_bg" ; + + actNewTab = new KAction( i18n( "Open in &New Tab" ), tab_new_x, 0, this, SLOT( slotPopupNewTab() ), konqyMenuClient->actionCollection(), "openintab" ); + actNewTab->setToolTip( i18n( "Open the document in a new tab" ) ); + doTabHandling = true; + } + + if (currentView->isHierarchicalView()) + itemFlags |= KParts::BrowserExtension::ShowCreateDirectory; + + KonqPopupMenu::KonqPopupFlags kpf = 0; + if ( showProperties ) + kpf |= KonqPopupMenu::ShowProperties; + else + kpf |= KonqPopupMenu::IsLink; // HACK + + QGuardedPtr<KonqPopupMenu> pPopupMenu = new KonqPopupMenu( + KonqBookmarkManager::self(), _items, + viewURL, + popupMenuCollection, + m_pMenuNew, + // This parent ensures that if the part destroys itself (e.g. KHTML redirection), + // it will close the popupmenu + currentView->part()->widget(), + kpf, + itemFlags ); + + if ( openedForViewURL && !viewURL.isLocalFile() ) + pPopupMenu->setURLTitle( currentView->caption() ); + + // We will need these if we call the newTab slot + popupItems = _items; + popupUrlArgs = _args; + popupUrlArgs.serviceType = QString::null; // Reset so that Open in New Window/Tab does mimetype detection + + connectActionCollection( pPopupMenu->actionCollection() ); + + pPopupMenu->factory()->addClient( konqyMenuClient ); + + if ( client ) + pPopupMenu->factory()->addClient( client ); + + KParts::BrowserExtension *be = ::qt_cast<KParts::BrowserExtension *>(sender()); + + if ( be ) + { + QObject::connect( this, SIGNAL(popupItemsDisturbed()), pPopupMenu, SLOT(close()) ); + QObject::connect( be, SIGNAL(itemsRemoved(const KFileItemList &)), + this, SLOT(slotItemsRemoved(const KFileItemList &)) ); + } + + QObject::disconnect( m_pMenuNew->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotFileNewAboutToShow()) ); + + QGuardedPtr<QObject> guard(this); // #149736 + pPopupMenu->exec( _global ); + + delete pPopupMenu; + + // We're sort of misusing KActionCollection here, but we need it for the actionStatusText signal... + // Anyway. If the action belonged to the view, and the view got deleted, we don't want ~KActionCollection + // to iterate over those deleted actions + KActionPtrList lst = popupMenuCollection.actions(); + KActionPtrList::iterator it = lst.begin(); + for ( ; it != lst.end() ; ++it ) + popupMenuCollection.take( *it ); + + if (guard.isNull()) { // the placement of this test is very important, double-check #149736 if moving stuff around + return; + } + + QObject::connect( m_pMenuNew->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotFileNewAboutToShow()) ); + + if ( be ) + { + QObject::disconnect( be, SIGNAL(itemsRemoved(const KFileItemList &)), + this, SLOT(slotItemsRemoved(const KFileItemList &)) ); + } + + delete konqyMenuClient; + m_popupEmbeddingServices.clear(); + popupItems.clear(); + + // Deleted by konqyMenuClient's actioncollection + //delete actNewTab; + //delete actNewWindow; + + delete actPaste; + + + //kdDebug(1202) << "-------- KonqMainWindow::slotPopupMenu() - m_oldView = " << m_oldView << ", currentView = " << currentView + //<< ", m_currentView = " << m_currentView << endl; + + // Restore current view if current is passive + if ( (m_oldView != currentView) && (currentView == m_currentView) && currentView->isPassiveMode() ) + { + //kdDebug() << "KonqMainWindow::slotPopupMenu restoring active view " << m_oldView << endl; + if ( m_currentView->browserExtension() ) + disconnectExtension( m_currentView->browserExtension() ); + if ( m_oldView ) + { + if ( m_oldView->browserExtension() ) + { + connectExtension( m_oldView->browserExtension() ); + m_currentView = m_oldView; + } + // Special case: RMB + renaming in sidebar; setFocus would abort editing. + QWidget* fw = focusWidget(); + if ( !fw || !::qt_cast<QLineEdit*>( fw ) ) + m_oldView->part()->widget()->setFocus(); + } + } +} + +void KonqMainWindow::slotItemsRemoved( const KFileItemList &items ) +{ + QPtrListIterator<KFileItem> it( items ); + for ( ; it.current(); ++it ) + { + if ( popupItems.contains( it.current() ) ) + { + emit popupItemsDisturbed(); + return; + } + } +} + +void KonqMainWindow::slotOpenEmbedded() +{ + QCString name = sender()->name(); + + m_popupService = m_popupEmbeddingServices[ name.toInt() ]->desktopEntryName(); + + m_popupEmbeddingServices.clear(); + + QTimer::singleShot( 0, this, SLOT( slotOpenEmbeddedDoIt() ) ); +} + +void KonqMainWindow::slotOpenEmbeddedDoIt() +{ + m_currentView->stop(); + m_currentView->setLocationBarURL(m_popupURL); + m_currentView->setTypedURL(QString::null); + if ( m_currentView->changeViewMode( m_popupServiceType, + m_popupService ) ) + m_currentView->openURL( m_popupURL, m_popupURL.pathOrURL() ); +} + +void KonqMainWindow::slotDatabaseChanged() +{ + if ( KSycoca::isChanged("mimetypes") ) + { + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + (*it)->callExtensionMethod( "refreshMimeTypes()" ); + } +} + +void KonqMainWindow::slotPopupPasteTo() +{ + if ( !m_currentView || m_popupURL.isEmpty() ) + return; + m_currentView->callExtensionURLMethod( "pasteTo(const KURL&)", m_popupURL ); +} + +void KonqMainWindow::slotReconfigure() +{ + reparseConfiguration(); +} + +void KonqMainWindow::reparseConfiguration() +{ + kdDebug(1202) << "KonqMainWindow::reparseConfiguration() !" << endl; + + KonqSettings::self()->readConfig(); + + m_bSaveViewPropertiesLocally = KonqSettings::saveViewPropertiesLocally(); + m_bHTMLAllowed = KonqSettings::htmlAllowed(); + + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + (*it)->reparseConfiguration(); +} + +void KonqMainWindow::saveProperties( KConfig *config ) +{ + m_pViewManager->saveViewProfile( *config, true /* save URLs */, false ); +} + +void KonqMainWindow::readProperties( KConfig *config ) +{ + kdDebug(1202) << "KonqMainWindow::readProperties( KConfig *config )" << endl; + m_pViewManager->loadViewProfile( *config, QString::null /*no profile name*/ ); +} + +void KonqMainWindow::setInitialFrameName( const QString &name ) +{ + m_initialFrameName = name; +} + +void KonqMainWindow::slotActionStatusText( const QString &text ) +{ + if ( !m_currentView ) + return; + + KonqFrameStatusBar *statusBar = m_currentView->frame()->statusbar(); + + if ( !statusBar ) + return; + + statusBar->message( text ); +} + +void KonqMainWindow::slotClearStatusText() +{ + if ( !m_currentView ) + return; + + KonqFrameStatusBar *statusBar = m_currentView->frame()->statusbar(); + + if ( !statusBar ) + return; + + statusBar->slotClear(); +} + +void KonqMainWindow::updateOpenWithActions() +{ + unplugActionList( "openwith" ); + + m_openWithActions.clear(); + + if (!kapp->authorizeKAction("openwith")) + return; + + const KTrader::OfferList & services = m_currentView->appServiceOffers(); + KTrader::OfferList::ConstIterator it = services.begin(); + KTrader::OfferList::ConstIterator end = services.end(); + for (; it != end; ++it ) + { + KAction *action = new KAction( i18n( "Open with %1" ).arg( (*it)->name() ), 0, 0, (*it)->desktopEntryName().latin1() ); + action->setIcon( (*it)->icon() ); + + connect( action, SIGNAL( activated() ), + this, SLOT( slotOpenWith() ) ); + + m_openWithActions.append( action ); + } + if ( services.count() > 0 ) + { + m_openWithActions.append( new KActionSeparator ); + plugActionList( "openwith", m_openWithActions ); + } +} + +QString KonqMainWindow::viewModeActionKey( KService::Ptr service ) +{ + QString library = service->library(); + // Group all non-builtin views together + QVariant builtIntoProp = service->property( "X-KDE-BrowserView-Built-Into" ); + if ( !builtIntoProp.isValid() || builtIntoProp.toString() != "konqueror" ) + library = "external"; + return library; +} + +void KonqMainWindow::updateViewModeActions() +{ + unplugViewModeActions(); + if ( m_viewModeMenu ) + { + QPtrListIterator<KRadioAction> it( m_viewModeActions ); + for (; it.current(); ++it ) + it.current()->unplugAll(); + delete m_viewModeMenu; + } + + m_viewModeMenu = 0; + m_toolBarViewModeActions.clear(); + m_viewModeActions.clear(); + + // if we changed the viewmode to something new, then we have to + // make sure to also clear our [libiconview,liblistview]->service-for-viewmode + // map + if ( m_viewModeToolBarServices.count() > 0 && + !m_viewModeToolBarServices.begin().data()->serviceTypes().contains( m_currentView->serviceType() ) ) + { + // Save the current map to the config file, for later reuse + saveToolBarServicesMap(); + + m_viewModeToolBarServices.clear(); + } + + KTrader::OfferList services = m_currentView->partServiceOffers(); + + if ( services.count() <= 1 ) + return; + + m_viewModeMenu = new KActionMenu( i18n( "&View Mode" ), this ); + + // a temporary map, just like the m_viewModeToolBarServices map, but + // mapping to a KonqViewModeAction object. It's just temporary as we + // of use it to group the viewmode actions (iconview,multicolumnview, + // treeview, etc.) into to two groups -> icon/list + // Although I wrote this now only of icon/listview it has to work for + // any view, that's why it's so general :) + QMap<QString,KonqViewModeAction*> groupedServiceMap; + + // Another temporary map, the preferred service for each library (2 entries in our example) + QMap<QString,QString> preferredServiceMap; + + KConfig * config = KGlobal::config(); + config->setGroup( "ModeToolBarServices" ); + + KTrader::OfferList::ConstIterator it = services.begin(); + KTrader::OfferList::ConstIterator end = services.end(); + for (; it != end; ++it ) + { + QVariant prop = (*it)->property( "X-KDE-BrowserView-Toggable" ); + if ( prop.isValid() && prop.toBool() ) // No toggable views in view mode + continue; + + KRadioAction *action; + + QString itname = (*it)->genericName(); + if (itname.isEmpty()) + itname = (*it)->name(); + + QString icon = (*it)->icon(); + if ( icon != QString::fromLatin1( "unknown" ) ) + // we *have* to specify a parent qobject, otherwise the exclusive group stuff doesn't work!(Simon) + action = new KRadioAction( itname, icon, 0, this, (*it)->desktopEntryName().ascii() ); + else + action = new KRadioAction( itname, 0, this, (*it)->desktopEntryName().ascii() ); + + action->setExclusiveGroup( "KonqMainWindow_ViewModes" ); + + connect( action, SIGNAL( toggled( bool ) ), + this, SLOT( slotViewModeToggle( bool ) ) ); + + m_viewModeActions.append( action ); + action->plug( m_viewModeMenu->popupMenu() ); + + const QString library = viewModeActionKey( *it ); + + // look if we already have a KonqViewModeAction (in the toolbar) + // for this component + QMap<QString,KonqViewModeAction*>::Iterator mapIt = groupedServiceMap.find( library ); + + // if we don't have -> create one + if ( mapIt == groupedServiceMap.end() ) + { + // default service on this action: the current one (i.e. the first one) + QString text = itname; + QString icon = (*it)->icon(); + QCString name = (*it)->desktopEntryName().latin1(); + //kdDebug(1202) << " Creating action for " << library << ". Default service " << itname << endl; + + // if we previously changed the viewmode (see slotViewModeToggle!) + // then we will want to use the previously used settings (previous as + // in before the actions got deleted) + QMap<QString,KService::Ptr>::ConstIterator serviceIt = m_viewModeToolBarServices.find( library ); + if ( serviceIt != m_viewModeToolBarServices.end() ) + { + kdDebug(1202) << " Setting action for " << library << " to " << (*serviceIt)->name() << endl; + text = (*serviceIt)->genericName(); + if (text.isEmpty()) + text = (*serviceIt)->name(); + icon = (*serviceIt)->icon(); + name = (*serviceIt)->desktopEntryName().ascii(); + } else + { + // if we don't have it in the map, we should look for a setting + // for this library in the config file. + QString preferredService = config->readEntry( library ); + if ( !preferredService.isEmpty() && name != preferredService.latin1() ) + { + //kdDebug(1202) << " Inserting into preferredServiceMap(" << library << ") : " << preferredService << endl; + // The preferred service isn't the current one, so remember to set it later + preferredServiceMap[ library ] = preferredService; + } + } + + KonqViewModeAction *tbAction = new KonqViewModeAction( text, + icon, + this, + name ); + + tbAction->setExclusiveGroup( "KonqMainWindow_ToolBarViewModes" ); + + tbAction->setChecked( action->isChecked() ); + + connect( tbAction, SIGNAL( toggled( bool ) ), + this, SLOT( slotViewModeToggle( bool ) ) ); + + m_toolBarViewModeActions.append( tbAction ); + + mapIt = groupedServiceMap.insert( library, tbAction ); + } + + // Check the actions (toolbar button and menu item) if they correspond to the current view + bool bIsCurrentView = (*it)->desktopEntryName() == m_currentView->service()->desktopEntryName(); + if ( bIsCurrentView ) + { + (*mapIt)->setChecked( true ); + action->setChecked( true ); + } + + // Set the contents of the button from the current service, either if it's the current view + // or if it's our preferred service for this button (library) + if ( bIsCurrentView + || ( preferredServiceMap.contains( library ) && (*it)->desktopEntryName() == preferredServiceMap[ library ] ) ) + { + //kdDebug(1202) << " Changing action for " << library << " into service " << (*it)->name() << endl; + + QString mapitname = (*it)->genericName(); + if (mapitname.isEmpty()) + mapitname = (*it)->name(); + (*mapIt)->setText( mapitname ); + (*mapIt)->setIcon( (*it)->icon() ); + (*mapIt)->setName( (*it)->desktopEntryName().ascii() ); // tricky... + preferredServiceMap.remove( library ); // The current view has priority over the saved settings + } + + // plug action also into the delayed popupmenu of appropriate toolbar action + action->plug( (*mapIt)->popupMenu() ); + } + +#ifndef NDEBUG + // Note that this can happen (map not empty) when a inode/directory view is removed, + // and remains in the KConfig file. + Q_ASSERT( preferredServiceMap.isEmpty() ); + QMap<QString,QString>::Iterator debugIt = preferredServiceMap.begin(); + QMap<QString,QString>::Iterator debugEnd = preferredServiceMap.end(); + for ( ; debugIt != debugEnd ; ++debugIt ) + kdDebug(1202) << " STILL IN preferredServiceMap : " << debugIt.key() << " | " << debugIt.data() << endl; +#endif + + if ( !m_currentView->isToggleView() ) // No view mode for toggable views + // (The other way would be to enforce a better servicetype for them, than Browser/View) + if ( /* already tested: services.count() > 1 && */ m_viewModeMenu ) + plugViewModeActions(); +} + +void KonqMainWindow::saveToolBarServicesMap() +{ + QMap<QString,KService::Ptr>::ConstIterator serviceIt = m_viewModeToolBarServices.begin(); + QMap<QString,KService::Ptr>::ConstIterator serviceEnd = m_viewModeToolBarServices.end(); + KConfig * config = KGlobal::config(); + config->setGroup( "ModeToolBarServices" ); + for ( ; serviceIt != serviceEnd ; ++serviceIt ) + config->writeEntry( serviceIt.key(), serviceIt.data()->desktopEntryName() ); + config->sync(); +} + +void KonqMainWindow::plugViewModeActions() +{ + QPtrList<KAction> lst; + lst.append( m_viewModeMenu ); + plugActionList( "viewmode", lst ); + // display the toolbar viewmode icons only for inode/directory, as here we have dedicated icons + if ( m_currentView && m_currentView->supportsServiceType( "inode/directory" ) ) + plugActionList( "viewmode_toolbar", m_toolBarViewModeActions ); +} + +void KonqMainWindow::unplugViewModeActions() +{ + unplugActionList( "viewmode" ); + unplugActionList( "viewmode_toolbar" ); +} + +KonqMainWindowIface* KonqMainWindow::dcopObject() +{ + return m_dcopObject; +} + +void KonqMainWindow::updateBookmarkBar() +{ + KToolBar * bar = static_cast<KToolBar *>( child( "bookmarkToolBar", "KToolBar" ) ); + + if (!bar) return; + + // hide if empty + if (m_paBookmarkBar && bar->count() == 0 ) + bar->hide(); + +} + +void KonqMainWindow::closeEvent( QCloseEvent *e ) +{ + kdDebug(1202) << "KonqMainWindow::closeEvent begin" << endl; + // This breaks session management (the window is withdrawn in kwin) + // so let's do this only when closed by the user. + if ( static_cast<KonquerorApplication *>(kapp)->closedByUser() ) + { + if ( viewManager()->docContainer() && viewManager()->docContainer()->frameType()=="Tabs" ) + { + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(viewManager()->docContainer()); + if ( tabContainer->count() > 1 ) + { + KConfig *config = KGlobal::config(); + KConfigGroupSaver cs( config, QString::fromLatin1("Notification Messages") ); + + if ( !config->hasKey( "MultipleTabConfirm" ) ) + { + switch ( + KMessageBox::warningYesNoCancel( + this, + i18n("You have multiple tabs open in this window, " + "are you sure you want to quit?"), + i18n("Confirmation"), + KStdGuiItem::quit(), + KGuiItem(i18n( "C&lose Current Tab" ), "tab_remove"), + "MultipleTabConfirm" + ) + ) { + case KMessageBox::Yes : + break; + case KMessageBox::No : + { + e->ignore(); + slotRemoveTab(); + return; + } + break; + case KMessageBox::Cancel : + { + e->ignore(); + return; + } + } + } + } + + KonqView *originalView = m_currentView; + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) { + KonqView *view = it.data(); + if (view && view->part() && (view->part()->metaObject()->findProperty("modified") != -1) ) { + QVariant prop = view->part()->property("modified"); + if (prop.isValid() && prop.toBool()) { + m_pViewManager->showTab( view ); + if ( KMessageBox::warningContinueCancel( this, + i18n("This tab contains changes that have not been submitted.\nClosing the window will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"exit"), "discardchangesclose") != KMessageBox::Continue ) + { + e->ignore(); + m_pViewManager->showTab( originalView ); + return; + } + } + } + } +// m_pViewManager->showTab( originalView ); + } + else if ( m_currentView && m_currentView->part() && + (m_currentView->part()->metaObject()->findProperty("modified") != -1) ) + { + QVariant prop = m_currentView->part()->property("modified"); + if (prop.isValid() && prop.toBool()) + if ( KMessageBox::warningContinueCancel( this, + i18n("This page contains changes that have not been submitted.\nClosing the window will discard these changes."), + i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"exit"), "discardchangesclose") != KMessageBox::Continue ) + { + e->ignore(); + return; + } + } + + // save size to have something to restore if the profile does not contain size + saveWindowSize(); + + hide(); + qApp->flushX(); + } + // We're going to close - tell the parts + MapViews::ConstIterator it = m_mapViews.begin(); + MapViews::ConstIterator end = m_mapViews.end(); + for (; it != end; ++it ) + { + if ( (*it)->part() && (*it)->part()->widget() ) + QApplication::sendEvent( (*it)->part()->widget(), e ); + } + KParts::MainWindow::closeEvent( e ); + if( isPreloaded() && !kapp->sessionSaving()) + { // queryExit() refused closing, hide instead + hide(); + } + kdDebug(1202) << "KonqMainWindow::closeEvent end" << endl; +} + +bool KonqMainWindow::queryExit() +{ + if( kapp->sessionSaving()) // *sigh* + return true; + return !stayPreloaded(); +} + +void KonqMainWindow::setIcon( const QPixmap& pix ) +{ + KParts::MainWindow::setIcon( pix ); + + QPixmap big = pix; + + QString url = m_combo->currentText(); + + if ( !url.isEmpty() ) + big = KonqPixmapProvider::self()->pixmapFor( url, KIcon::SizeMedium ); + + KWin::setIcons( winId(), big, pix ); +} + +void KonqMainWindow::slotIntro() +{ + openURL( 0L, KURL("about:konqueror") ); +} + +void KonqMainWindow::goURL() +{ + QLineEdit *lineEdit = m_combo->lineEdit(); + if ( !lineEdit ) + return; + + QKeyEvent event( QEvent::KeyPress, Key_Return, '\n', 0 ); + QApplication::sendEvent( lineEdit, &event ); +} + +void KonqMainWindow::slotLocationLabelActivated() +{ + focusLocationBar(); + m_combo->lineEdit()->selectAll(); +} + +void KonqMainWindow::slotOpenURL( const KURL& url ) +{ + openURL( 0L, url ); +} + +bool KonqMainWindow::sidebarVisible() const +{ +KAction *a = m_toggleViewGUIClient->action("konq_sidebartng"); +return (a && static_cast<KToggleAction*>(a)->isChecked()); +} + +void KonqMainWindow::slotAddWebSideBar(const KURL& url, const QString& name) +{ + if (url.url().isEmpty() && name.isEmpty()) + return; + + kdDebug(1202) << "Requested to add URL " << url << " [" << name << "] to the sidebar!" << endl; + + KAction *a = m_toggleViewGUIClient->action("konq_sidebartng"); + if (!a) { + KMessageBox::sorry(0L, i18n("Your sidebar is not functional or unavailable. A new entry cannot be added."), i18n("Web Sidebar")); + return; + } + + int rc = KMessageBox::questionYesNo(0L, + i18n("Add new web extension \"%1\" to your sidebar?") + .arg(name.isEmpty() ? name : url.prettyURL()), + i18n("Web Sidebar"),i18n("Add"),i18n("Do Not Add")); + + if (rc == KMessageBox::Yes) { + // Show the sidebar + if (!static_cast<KToggleAction*>(a)->isChecked()) { + a->activate(); + } + + // Tell it to add a new panel + MapViews::ConstIterator it; + for (it = viewMap().begin(); it != viewMap().end(); ++it) { + KonqView *view = it.data(); + if (view) { + KService::Ptr svc = view->service(); + if (svc->desktopEntryName() == "konq_sidebartng") { + emit view->browserExtension()->addWebSideBar(url, name); + break; + } + } + } + } +} + +void KonqMainWindow::bookmarksIntoCompletion( const KBookmarkGroup& group ) +{ + static const QString& http = KGlobal::staticQString( "http" ); + static const QString& ftp = KGlobal::staticQString( "ftp" ); + + if ( group.isNull() ) + return; + + for ( KBookmark bm = group.first(); + !bm.isNull(); bm = group.next(bm) ) { + if ( bm.isGroup() ) { + bookmarksIntoCompletion( bm.toGroup() ); + continue; + } + + KURL url = bm.url(); + if ( !url.isValid() ) + continue; + + QString u = url.prettyURL(); + s_pCompletion->addItem( u ); + + if ( url.isLocalFile() ) + s_pCompletion->addItem( url.path() ); + else if ( url.protocol() == http ) + s_pCompletion->addItem( u.mid( 7 )); + else if ( url.protocol() == ftp && + url.host().startsWith( ftp ) ) + s_pCompletion->addItem( u.mid( 6 ) ); + } +} + +void KonqMainWindow::connectActionCollection( KActionCollection *coll ) +{ + connect( coll, SIGNAL( actionStatusText( const QString & ) ), + this, SLOT( slotActionStatusText( const QString & ) ) ); + connect( coll, SIGNAL( clearStatusText() ), + this, SLOT( slotClearStatusText() ) ); +} + +void KonqMainWindow::disconnectActionCollection( KActionCollection *coll ) +{ + disconnect( coll, SIGNAL( actionStatusText( const QString & ) ), + this, SLOT( slotActionStatusText( const QString & ) ) ); + disconnect( coll, SIGNAL( clearStatusText() ), + this, SLOT( slotClearStatusText() ) ); +} + +// +// the smart popup completion code , <[email protected]> +// + +// prepend http://www. or http:// if there's no protocol in 's' +// used only when there are no completion matches +static QString hp_tryPrepend( const QString& s ) +{ + if( s.isEmpty() || s[ 0 ] == '/' ) + return QString::null; + for( unsigned int pos = 0; + pos < s.length() - 2; // 4 = ://x + ++pos ) + { + if( s[ pos ] == ':' && s[ pos + 1 ] == '/' && s[ pos + 2 ] == '/' ) + return QString::null; + if( !s[ pos ].isLetter() ) + break; + } + return ( s.startsWith( "www." ) ? "http://" : "http://www." ) + s; +} + + +static void hp_removeDupe( KCompletionMatches& l, const QString& dupe, + KCompletionMatches::Iterator it_orig ) +{ + for( KCompletionMatches::Iterator it = l.begin(); + it != l.end(); + ) { + if( it == it_orig ) { + ++it; + continue; + } + if( (*it).value() == dupe ) { + (*it_orig).first = kMax( (*it_orig).first, (*it).index()); + it = l.remove( it ); + continue; + } + ++it; + } +} + +// remove duplicates like 'http://www.kde.org' and 'http://www.kde.org/' +// (i.e. the trailing slash) +// some duplicates are also created by prepending protocols +static void hp_removeDuplicates( KCompletionMatches& l ) +{ + QString http = "http://"; + QString ftp = "ftp://ftp."; + QString file = "file:"; + QString file2 = "file://"; + l.removeDuplicates(); + for( KCompletionMatches::Iterator it = l.begin(); + it != l.end(); + ++it ) { + QString str = (*it).value(); + if( str.startsWith( http )) { + if( str.find( '/', 7 ) < 0 ) { // http://something<noslash> + hp_removeDupe( l, str + '/', it ); + hp_removeDupe( l, str.mid( 7 ) + '/', it ); + } else if( str[ str.length() - 1 ] == '/' ) { + hp_removeDupe( l, str.left( str.length() - 1 ), it ); + hp_removeDupe( l, str.left( str.length() - 1 ).mid( 7 ), it ); + } + hp_removeDupe( l, str.mid( 7 ), it ); + } + else if( str.startsWith( ftp )) // ftp://ftp. + hp_removeDupe( l, str.mid( 6 ), it ); // remove dupes without ftp:// + else if( str.startsWith( file2 )) + hp_removeDupe( l, str.mid( 7 ), it ); // remove dupes without file:// + else if( str.startsWith( file )) + hp_removeDupe( l, str.mid( 5 ), it ); // remove dupes without file: + } +} + +static void hp_removeCommonPrefix( KCompletionMatches& l, const QString& prefix ) +{ + for( KCompletionMatches::Iterator it = l.begin(); + it != l.end(); + ) { + if( (*it).value().startsWith( prefix )) { + it = l.remove( it ); + continue; + } + ++it; + } +} + +// don't include common prefixes like 'http://', i.e. when s == 'h', include +// http://hotmail.com but don't include everything just starting with 'http://' +static void hp_checkCommonPrefixes( KCompletionMatches& matches, const QString& s ) +{ + static const char* const prefixes[] = { + "http://", + "https://", + "www.", + "ftp://", + "http://www.", + "https://www.", + "ftp://ftp.", + "file:", + "file://", + NULL }; + for( const char* const *pos = prefixes; + *pos != NULL; + ++pos ) { + QString prefix = *pos; + if( prefix.startsWith( s )) { + hp_removeCommonPrefix( matches, prefix ); + } + } +} + +QStringList KonqMainWindow::historyPopupCompletionItems( const QString& s) +{ + const QString http = "http://"; + const QString https = "https://"; + const QString www = "http://www."; + const QString wwws = "https://www."; + const QString ftp = "ftp://"; + const QString ftpftp = "ftp://ftp."; + const QString file = "file:"; // without /, because people enter /usr etc. + const QString file2 = "file://"; + if( s.isEmpty()) + return QStringList(); + KCompletionMatches matches= s_pCompletion->allWeightedMatches( s ); + hp_checkCommonPrefixes( matches, s ); + bool checkDuplicates = false; + if ( !s.startsWith( ftp ) ) { + matches += s_pCompletion->allWeightedMatches( ftp + s ); + if( QString( "ftp." ).startsWith( s )) + hp_removeCommonPrefix( matches, ftpftp ); + checkDuplicates = true; + } + if ( !s.startsWith( https ) ) { + matches += s_pCompletion->allWeightedMatches( https + s ); + if( QString( "www." ).startsWith( s )) + hp_removeCommonPrefix( matches, wwws ); + checkDuplicates = true; + } + if ( !s.startsWith( http )) { + matches += s_pCompletion->allWeightedMatches( http + s ); + if( QString( "www." ).startsWith( s )) + hp_removeCommonPrefix( matches, www ); + checkDuplicates = true; + } + if ( !s.startsWith( www ) ) { + matches += s_pCompletion->allWeightedMatches( www + s ); + checkDuplicates = true; + } + if ( !s.startsWith( wwws ) ) { + matches += s_pCompletion->allWeightedMatches( wwws + s ); + checkDuplicates = true; + } + if ( !s.startsWith( ftpftp ) ) { + matches += s_pCompletion->allWeightedMatches( ftpftp + s ); + checkDuplicates = true; + } + if ( !s.startsWith( file ) ) { + matches += s_pCompletion->allWeightedMatches( file + s ); + checkDuplicates = true; + } + if ( !s.startsWith( file2 ) ) { + matches += s_pCompletion->allWeightedMatches( file2 + s ); + checkDuplicates = true; + } + if( checkDuplicates ) + hp_removeDuplicates( matches ); + QStringList items = matches.list(); + if( items.count() == 0 + && !s.contains( ':' ) && s[ 0 ] != '/' ) + { + QString pre = hp_tryPrepend( s ); + if( !pre.isNull()) + items += pre; + } + return items; +} + +#ifndef NDEBUG +void KonqMainWindow::dumpViewList() +{ + MapViews::Iterator end = m_mapViews.end(); + + kdDebug(1202) << m_mapViews.count() << "Views" << endl; + + for (MapViews::Iterator it = m_mapViews.begin(); it != end; it++) + { + kdDebug(1202) << it.data() << endl; + } +} +#endif + +// KonqFrameContainerBase implementation BEGIN + +/** + * Call this after inserting a new frame into the splitter. + */ +void KonqMainWindow::insertChildFrame( KonqFrameBase * frame, int /*index*/ ) +{ + m_pChildFrame = frame; + m_pActiveChild = frame; + frame->setParentContainer(this); + setCentralWidget( frame->widget() ); +} + +/** + * Call this before deleting one of our children. + */ +void KonqMainWindow::removeChildFrame( KonqFrameBase * /*frame*/ ) +{ + m_pChildFrame = 0L; + m_pActiveChild = 0L; +} + +void KonqMainWindow::saveConfig( KConfig* config, const QString &prefix, bool saveURLs, KonqFrameBase* docContainer, int id, int depth ) { if( m_pChildFrame ) m_pChildFrame->saveConfig( config, prefix, saveURLs, docContainer, id, depth); } + +void KonqMainWindow::copyHistory( KonqFrameBase *other ) { if( m_pChildFrame ) m_pChildFrame->copyHistory( other ); } + +void KonqMainWindow::printFrameInfo( const QString &spaces ) { if( m_pChildFrame ) m_pChildFrame->printFrameInfo( spaces ); } + +void KonqMainWindow::reparentFrame( QWidget* /*parent*/, + const QPoint & /*p*/, bool /*showIt*/ ) { return; } + +KonqFrameContainerBase* KonqMainWindow::parentContainer()const { return 0L; } +void KonqMainWindow::setParentContainer(KonqFrameContainerBase* /*parent*/) { return; } + +void KonqMainWindow::setTitle( const QString &/*title*/ , QWidget* /*sender*/) { return; } +void KonqMainWindow::setTabIcon( const KURL &/*url*/, QWidget* /*sender*/ ) { return; } + +QWidget* KonqMainWindow::widget() { return this; } + +void KonqMainWindow::listViews( ChildViewList *viewList ) { if( m_pChildFrame ) m_pChildFrame->listViews( viewList ); } + +QCString KonqMainWindow::frameType() { return QCString("MainWindow"); } + +KonqFrameBase* KonqMainWindow::childFrame()const { return m_pChildFrame; } + +void KonqMainWindow::setActiveChild( KonqFrameBase* /*activeChild*/ ) { return; } + +bool KonqMainWindow::isMimeTypeAssociatedWithSelf( const QString &mimeType ) +{ + return isMimeTypeAssociatedWithSelf( mimeType, KServiceTypeProfile::preferredService( mimeType, "Application" ) ); +} + +bool KonqMainWindow::isMimeTypeAssociatedWithSelf( const QString &/*mimeType*/, const KService::Ptr &offer ) +{ + // Prevention against user stupidity : if the associated app for this mimetype + // is konqueror/kfmclient, then we'll loop forever. So we have to + // 1) force embedding first, if that works we're ok + // 2) check what KRun is going to do before calling it. + return ( offer && ( offer->desktopEntryName() == "konqueror" || + offer->exec().stripWhiteSpace().startsWith( "kfmclient" ) ) ); +} + +// KonqFrameContainerBase implementation END + +void KonqMainWindow::setPreloadedFlag( bool preloaded ) +{ + if( s_preloaded == preloaded ) + return; + s_preloaded = preloaded; + if( s_preloaded ) + { + kapp->disableSessionManagement(); // dont restore preloaded konqy's + return; // was registered before calling this + } + delete s_preloadedWindow; // preloaded state was abandoned without reusing the window + s_preloadedWindow = NULL; + kapp->enableSessionManagement(); // enable SM again + DCOPRef ref( "kded", "konqy_preloader" ); + ref.send( "unregisterPreloadedKonqy", kapp->dcopClient()->appId()); +} + +void KonqMainWindow::setPreloadedWindow( KonqMainWindow* window ) +{ + s_preloadedWindow = window; + if( window == NULL ) + return; + window->viewManager()->clear(); + KIO::Scheduler::unregisterWindow( window ); +} + +// used by preloading - this KonqMainWindow will be reused, reset everything +// that won't be reset by loading a profile +void KonqMainWindow::resetWindow() +{ + char data[ 1 ]; + // empty append to get current X timestamp + QWidget tmp_widget; + XChangeProperty( qt_xdisplay(), tmp_widget.winId(), XA_WM_CLASS, XA_STRING, 8, + PropModeAppend, (unsigned char*) &data, 0 ); + XEvent ev; + XWindowEvent( qt_xdisplay(), tmp_widget.winId(), PropertyChangeMask, &ev ); + long x_time = ev.xproperty.time; + // bad hack - without updating the _KDE_NET_WM_USER_CREATION_TIME property, + // KWin will apply don't_steal_focus to this window, and will not make it active + // (shows mainly with 'konqueror --preload') + static Atom atom = XInternAtom( qt_xdisplay(), "_KDE_NET_WM_USER_CREATION_TIME", False ); + XChangeProperty( qt_xdisplay(), winId(), atom, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *) &x_time, 1); + extern Time qt_x_user_time; // reset also user time, so that this window + qt_x_user_time = CurrentTime; // won't have _NET_WM_USER_TIME set +#if !KDE_IS_VERSION( 3, 2, 90 ) // _KDE_NET_USER_TIME is obsolete + static Atom atom2 = XInternAtom( qt_xdisplay(), "_KDE_NET_USER_TIME", False ); + timeval tv; + gettimeofday( &tv, NULL ); + unsigned long now = tv.tv_sec * 10 + tv.tv_usec / 100000; + XChangeProperty(qt_xdisplay(), winId(), atom2, XA_CARDINAL, + 32, PropModeReplace, (unsigned char *)&now, 1); +#endif + static Atom atom3 = XInternAtom( qt_xdisplay(), "_NET_WM_USER_TIME", False ); + XDeleteProperty( qt_xdisplay(), winId(), atom3 ); +// Qt remembers the iconic state if the window was withdrawn while on another virtual desktop + clearWState( WState_Minimized ); + ignoreInitialGeometry(); + kapp->setTopWidget( this ); // set again the default window icon +} + +bool KonqMainWindow::event( QEvent* e ) +{ + if( e->type() == QEvent::DeferredDelete ) + { + // since the preloading code tries to reuse KonqMainWindow, + // the last window shouldn't be really deleted, but only hidden + // deleting WDestructiveClose windows is done using deleteLater(), + // so catch QEvent::DefferedDelete and check if this window should stay + if( stayPreloaded()) + { + setWFlags(WDestructiveClose); // was reset before deleteLater() + return true; // no deleting + } + } + return KParts::MainWindow::event( e ); +} + +bool KonqMainWindow::stayPreloaded() +{ + // last window? + if( mainWindowList()->count() > 1 ) + return false; + // not running in full KDE environment? + if( getenv( "KDE_FULL_SESSION" ) == NULL || getenv( "KDE_FULL_SESSION" )[ 0 ] == '\0' ) + return false; + // not the same user like the one running the session (most likely we're run via sudo or something) + if( getenv( "KDE_SESSION_UID" ) != NULL && uid_t( atoi( getenv( "KDE_SESSION_UID" ))) != getuid()) + return false; + if( KonqSettings::maxPreloadCount() == 0 ) + return false; + viewManager()->clear(); // reduce resource usage before checking it + if( !checkPreloadResourceUsage()) + return false; + DCOPRef ref( "kded", "konqy_preloader" ); + if( !ref.callExt( "registerPreloadedKonqy", DCOPRef::NoEventLoop, 5000, + kapp->dcopClient()->appId(), qt_xscreen())) + { + return false; + } + KonqMainWindow::setPreloadedFlag( true ); + kdDebug(1202) << "Konqy kept for preloading :" << kapp->dcopClient()->appId() << endl; + KonqMainWindow::setPreloadedWindow( this ); + return true; +} + +// try to avoid staying running when leaking too much memory +// this is checked by using mallinfo() and comparing +// memory usage during konqy startup and now, if the difference +// is too large -> leaks -> quit +// also, if this process is running for too long, or has been +// already reused too many times -> quit, just in case +bool KonqMainWindow::checkPreloadResourceUsage() +{ + if( +#ifndef NDEBUG + isatty( STDIN_FILENO ) || +#endif + isatty( STDOUT_FILENO ) || isatty( STDERR_FILENO )) + { + kdDebug(1202) << "Running from tty, not keeping for preloading" << endl; + return false; + } + int limit; + int usage = current_memory_usage( &limit ); + kdDebug(1202) << "Memory usage increase: " << ( usage - s_initialMemoryUsage ) + << " (" << usage << "/" << s_initialMemoryUsage << "), increase limit: " << limit << endl; + int max_allowed_usage = s_initialMemoryUsage + limit; + if( usage > max_allowed_usage ) // too much memory used? + { + kdDebug(1202) << "Not keeping for preloading due to high memory usage" << endl; + return false; + } + // working memory usage test ( usage != 0 ) makes others less strict + if( ++s_preloadUsageCount > ( usage != 0 ? 100 : 10 )) // reused too many times? + { + kdDebug(1202) << "Not keeping for preloading due to high usage count" << endl; + return false; + } + if( time( NULL ) > s_startupTime + 60 * 60 * ( usage != 0 ? 4 : 1 )) // running for too long? + { + kdDebug(1202) << "Not keeping for preloading due to long usage time" << endl; + return false; + } + return true; +} + +static int current_memory_usage( int* limit ) +{ +#ifdef __linux__ +// Check whole memory usage - VmSize + QFile f( QCString().sprintf( "/proc/%i/statm", getpid())); + if( f.open( IO_ReadOnly )) + { + QString line; + if( f.readLine( line, 1024 ) > 0 ) + { + line = line.stripWhiteSpace(); + int usage = line.section( ' ', 0, 0 ).toInt(); + if( usage > 0 ) + { + int pagesize = sysconf (_SC_PAGE_SIZE); + if( pagesize < 0 ) + pagesize = 4096; + if( limit != NULL ) + *limit = 16 * 1024 * 1024; + return usage * pagesize; + } + } + } + kdWarning() << "Couldn't read VmSize from /proc/*/statm." << endl; +#endif +// Check malloc() usage - very imprecise, but better than nothing. + int usage_sum = 0; +#if defined(KDE_MALLINFO_STDLIB) || defined(KDE_MALLINFO_MALLOC) + // ugly hack for kdecore/malloc + extern int kde_malloc_is_used; + free( calloc( 4, 4 )); // trigger setting kde_malloc_is_used + if( kde_malloc_is_used ) + { + struct mallinfo m = mallinfo(); + usage_sum = m.hblkhd + m.uordblks; + } + else + { + struct mallinfo m = mallinfo(); +#ifdef KDE_MALLINFO_FIELD_hblkhd + usage_sum += m.hblkhd; +#endif +#ifdef KDE_MALLINFO_FIELD_uordblks + usage_sum += m.uordblks; +#endif +#ifdef KDE_MALLINFO_FIELD_usmblks + usage_sum += m.usmblks; +#endif + } + // unlike /proc , this doesn't include things like size of dlopened modules, + // and also doesn't include malloc overhead + if( limit != NULL ) + *limit = 6 * 1024 * 1024; +#endif + return usage_sum; +} + +void KonqMainWindow::saveWindowSize() const +{ + QString savedGroup = KGlobal::config()->group(); + KGlobal::config()->setGroup( "KonqMainWindow_Size" ); + + KParts::MainWindow::saveWindowSize( KGlobal::config() ); + + KGlobal::config()->setGroup( savedGroup ); + KGlobal::config()->sync(); +} + +void KonqMainWindow::restoreWindowSize() +{ + QString savedGroup = KGlobal::config()->group(); + KGlobal::config()->setGroup( "KonqMainWindow_Size" ); + + KParts::MainWindow::restoreWindowSize( KGlobal::config() ); + + KGlobal::config()->setGroup( savedGroup ); +} + + +#include "konq_mainwindow.moc" +#include "konq_mainwindow_p.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/konqueror/konq_mainwindow.h b/konqueror/konq_mainwindow.h new file mode 100644 index 000000000..a99c485bf --- /dev/null +++ b/konqueror/konq_mainwindow.h @@ -0,0 +1,771 @@ +/* -*- c-basic-offset:2 -*- + This file is part of the KDE project + Copyright (C) 1998, 1999 Simon Hausmann <[email protected]> + Copyright (C) 2000-2004 David Faure <[email protected]> + + 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 __konq_mainwindow_h__ +#define __konq_mainwindow_h__ + +#include <qmap.h> +#include <qpoint.h> +#include <qtimer.h> +#include <qguardedptr.h> + +#include <kfileitem.h> +#include "konq_openurlrequest.h" + +#include <kparts/mainwindow.h> +#include <kbookmarkmanager.h> +#include <kcompletion.h> +#include <kurlcompletion.h> +#include <kglobalsettings.h> +#include <dcopobject.h> +#include <kxmlguifactory.h> +#include <kxmlguiclient.h> +#include <ktrader.h> +#include "konq_combo.h" +#include "konq_frame.h" + +class QFile; +class KAction; +class KActionCollection; +class KActionMenu; +class KBookmarkMenu; +class KCMultiDialog; +class KHistoryCombo; +class KNewMenu; +class KProgress; +class KSelectAction; +class KToggleAction; +class KonqBidiHistoryAction; +class KBookmarkBar; +class KonqView; +class KonqComboAction; +class KonqFrame; +class KonqFrameBase; +class KonqFrameContainerBase; +class KonqFrameContainer; +class KToolBarPopupAction; +class KonqLogoAction; +class KonqViewModeAction; +class KonqPart; +class KonqViewManager; +class OpenWithGUIClient; +class ToggleViewGUIClient; +class ViewModeGUIClient; +class KonqMainWindowIface; +class KonqDirPart; +class KonqRun; +class KURLRequester; +class KZip; +struct HistoryEntry; + +namespace KParts { + class BrowserExtension; + class BrowserHostExtension; + class ReadOnlyPart; + struct URLArgs; +} + +class KonqExtendedBookmarkOwner; + +class KonqMainWindow : public KParts::MainWindow, public KonqFrameContainerBase +{ + Q_OBJECT + Q_PROPERTY( int viewCount READ viewCount ) + Q_PROPERTY( int activeViewsCount READ activeViewsCount ) + Q_PROPERTY( int linkableViewsCount READ linkableViewsCount ) + Q_PROPERTY( QString locationBarURL READ locationBarURL ) + Q_PROPERTY( bool fullScreenMode READ fullScreenMode ) + Q_PROPERTY( QString currentTitle READ currentTitle ) + Q_PROPERTY( QString currentURL READ currentURL ) + Q_PROPERTY( bool isHTMLAllowed READ isHTMLAllowed ) + Q_PROPERTY( QString currentProfile READ currentProfile ) +public: + enum ComboAction { ComboClear, ComboAdd, ComboRemove }; + enum PageSecurity { NotCrypted, Encrypted, Mixed }; + + KonqMainWindow( const KURL &initialURL = KURL(), bool openInitialURL = true, const char *name = 0, const QString& xmluiFile="konqueror.rc"); + ~KonqMainWindow(); + + + /** + * Filters the URL and calls the main openURL method. + */ + void openFilteredURL( const QString & _url, KonqOpenURLRequest& _req); + + /** + * Filters the URL and calls the main openURL method. + */ + void openFilteredURL( const QString &_url, bool inNewTab = false, bool tempFile = false ); + + /** + * The main openURL method. + */ + void openURL( KonqView * view, const KURL & url, + const QString &serviceType = QString::null, + KonqOpenURLRequest & req = KonqOpenURLRequest::null, bool trustedSource = false ); + + /** + * Called by openURL when it knows the service type (either directly, + * or using KonqRun) + */ + bool openView( QString serviceType, const KURL &_url, KonqView *childView, + KonqOpenURLRequest & req = KonqOpenURLRequest::null ); + + + void abortLoading(); + + void openMultiURL( KURL::List url ); + + KonqViewManager *viewManager() const { return m_pViewManager; } + + // Central widget of the mainwindow, never 0L + QWidget *mainWidget() const; + + virtual QWidget *createContainer( QWidget *parent, int index, const QDomElement &element, int &id ); + virtual void removeContainer( QWidget *container, QWidget *parent, QDomElement &element, int id ); + + virtual void saveProperties( KConfig *config ); + virtual void readProperties( KConfig *config ); + + void setInitialFrameName( const QString &name ); + + KonqMainWindowIface * dcopObject(); + + void reparseConfiguration(); + + void insertChildView( KonqView *childView ); + void removeChildView( KonqView *childView ); + KonqView *childView( KParts::ReadOnlyPart *view ); + KonqView *childView( KParts::ReadOnlyPart *callingPart, const QString &name, KParts::BrowserHostExtension **hostExtension, KParts::ReadOnlyPart **part ); + + // dcop idl bug! it can't handle KonqMainWindow *&mainWindow + static KonqView *findChildView( KParts::ReadOnlyPart *callingPart, const QString &name, KonqMainWindow **mainWindow, KParts::BrowserHostExtension **hostExtension, KParts::ReadOnlyPart **part ); + + // Total number of views + int viewCount() const { return m_mapViews.count(); } + + // Number of views not in "passive" mode + int activeViewsCount() const; + + // Number of views that can be linked, i.e. not with "follow active view" behavior + int linkableViewsCount() const; + + // Number of main views (non-toggle non-passive views) + int mainViewsCount() const; + + typedef QMap<KParts::ReadOnlyPart *, KonqView *> MapViews; + + const MapViews & viewMap() const { return m_mapViews; } + + KonqView *currentView() const { return m_currentView; } + + KParts::ReadOnlyPart *currentPart() const; + + /** URL of current part, or URLs of selected items for directory views */ + KURL::List currentURLs() const; + + // Only valid if there are one or two views + KonqView * otherView( KonqView * view ) const; + + virtual void customEvent( QCustomEvent *event ); + + /// Overloaded of KMainWindow + virtual void setCaption( const QString &caption ); + + /** + * Reimplemented for internal reasons. The API is not affected. + */ + virtual void show(); + + /** + * Change URL displayed in the location bar + */ + void setLocationBarURL( const QString &url ); + /** + * Overload for convenience + */ + void setLocationBarURL( const KURL &url ); + /** + * Return URL displayed in the location bar - for KonqViewManager + */ + QString locationBarURL() const; + void focusLocationBar(); + + /** + * Set page security related to current view + */ + void setPageSecurity( PageSecurity ); + + void enableAllActions( bool enable ); + + void disableActionsNoView(); + + void updateToolBarActions( bool pendingActions = false ); + void updateOpenWithActions(); + void updateViewModeActions(); + void updateViewActions(); + + bool sidebarVisible() const; + + void setShowHTML( bool b ); + + void showHTML( KonqView * view, bool b, bool _activateView ); + + bool fullScreenMode() const { return m_ptaFullScreen->isChecked(); } + + /** + * @return the "link view" action, for checking/unchecking from KonqView + */ + KToggleAction * linkViewAction()const { return m_paLinkView; } + + void enableAction( const char * name, bool enabled ); + void setActionText( const char * name, const QString& text ); + + /** + * The default settings "allow HTML" - the one used when creating a new view + * Might not match the current view ! + */ + bool isHTMLAllowed() const { return m_bHTMLAllowed; } + + bool saveViewPropertiesLocally() const { return m_bSaveViewPropertiesLocally; } + + static QPtrList<KonqMainWindow> *mainWindowList() { return s_lstViews; } + + // public for konq_guiclients + void viewCountChanged(); + + // for the view manager + void currentProfileChanged(); + + // operates on all combos of all mainwindows of this instance + // up to now adds an entry or clears all entries + static void comboAction( int action, const QString& url, + const QCString& objId ); + +#ifndef NDEBUG + void dumpViewList(); +#endif + + // KonqFrameContainerBase implementation BEGIN + + /** + * Call this after inserting a new frame into the splitter. + */ + void insertChildFrame( KonqFrameBase * frame, int index = -1 ); + /** + * Call this before deleting one of our children. + */ + void removeChildFrame( KonqFrameBase * frame ); + + void saveConfig( KConfig* config, const QString &prefix, bool saveURLs, KonqFrameBase* docContainer, int id = 0, int depth = 0 ); + + void copyHistory( KonqFrameBase *other ); + + void printFrameInfo( const QString &spaces ); + + void reparentFrame( QWidget* parent, + const QPoint & p, bool showIt=FALSE ); + + KonqFrameContainerBase* parentContainer()const; + void setParentContainer(KonqFrameContainerBase* parent); + + void setTitle( const QString &title , QWidget* sender); + void setTabIcon( const KURL &url, QWidget* sender ); + + QWidget* widget(); + + void listViews( ChildViewList *viewList ); + QCString frameType(); + + KonqFrameBase* childFrame()const; + + void setActiveChild( KonqFrameBase* activeChild ); + + // KonqFrameContainerBase implementation END + + KonqFrameBase* workingTab()const { return m_pWorkingTab; } + void setWorkingTab( KonqFrameBase* tab ) { m_pWorkingTab = tab; } + + static bool isMimeTypeAssociatedWithSelf( const QString &mimeType ); + static bool isMimeTypeAssociatedWithSelf( const QString &mimeType, const KService::Ptr &offer ); + + void resetWindow(); + + static void setPreloadedFlag( bool preloaded ); + static bool isPreloaded() { return s_preloaded; } + static void setPreloadedWindow( KonqMainWindow* ); + static KonqMainWindow* preloadedWindow() { return s_preloadedWindow; } + + QString currentTitle() const; + QString currentURL() const; + QString currentProfile() const; + + QStringList configModules() const; + + void saveWindowSize() const; + void restoreWindowSize(); + +signals: + void viewAdded( KonqView *view ); + void viewRemoved( KonqView *view ); + void popupItemsDisturbed(); + +public slots: + void slotCtrlTabPressed(); + + // for KBookmarkMenu and KBookmarkBar + void slotFillContextMenu( const KBookmark &, QPopupMenu * ); + void slotOpenBookmarkURL( const QString & url, Qt::ButtonState state ); + + void slotPopupMenu( const QPoint &_global, const KURL &_url, const QString &_mimeType, mode_t mode ); + void slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KURL &_url, const QString &_mimeType, mode_t mode ); + void slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KURL &_url, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags f, mode_t mode ); + + void slotPopupMenu( const QPoint &_global, const KFileItemList &_items ); + void slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KFileItemList &_items ); + void slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KFileItemList &_items, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags _flags ); + + + void slotPopupMenu( KXMLGUIClient *client, const QPoint &_global, const KFileItemList &_items, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags f, bool showProperties ); + + /** + * __NEEEEVER__ call this method directly. It relies on sender() (the part) + */ + void slotOpenURLRequest( const KURL &url, const KParts::URLArgs &args ); + + void openURL( KonqView *childView, const KURL &url, const KParts::URLArgs &args ); + + void slotCreateNewWindow( const KURL &url, const KParts::URLArgs &args ); + void slotCreateNewWindow( const KURL &url, const KParts::URLArgs &args, + const KParts::WindowArgs &windowArgs, KParts::ReadOnlyPart *&part ); + + void slotNewWindow(); + void slotDuplicateWindow(); + void slotSendURL(); + void slotSendFile(); + void slotCopyFiles(); + void slotMoveFiles(); + void slotNewDir(); + void slotOpenTerminal(); + void slotOpenLocation(); + void slotToolFind(); + + // View menu + void slotViewModeToggle( bool toggle ); + void slotShowHTML(); + void slotLockView(); + void slotLinkView(); + void slotReload( KonqView* view = 0L ); + void slotStop(); + + // Go menu + void slotUp(); + void slotUp(KAction::ActivationReason, Qt::ButtonState state); + void slotUpDelayed(); + void slotBack(); + void slotBack(KAction::ActivationReason, Qt::ButtonState state); + void slotForward(); + void slotForward(KAction::ActivationReason, Qt::ButtonState state); + void slotHome(); + void slotHome(KAction::ActivationReason, Qt::ButtonState state); + void slotGoSystem(); + void slotGoApplications(); + void slotGoMedia(); + void slotGoNetworkFolders(); + void slotGoSettings(); + void slotGoDirTree(); + void slotGoTrash(); + void slotGoAutostart(); + void slotGoHistory(); + + void slotConfigure(); + void slotConfigureToolbars(); + void slotConfigureExtensions(); + void slotConfigureSpellChecking(); + void slotNewToolbarConfig(); + + void slotUndoAvailable( bool avail ); + + void slotPartChanged( KonqView *childView, KParts::ReadOnlyPart *oldPart, KParts::ReadOnlyPart *newPart ); + + void slotRunFinished(); + void slotClearLocationBar( KAction::ActivationReason reason, Qt::ButtonState state ); + + // reimplement from KParts::MainWindow + virtual void slotSetStatusBarText( const QString &text ); + + // public for KonqViewManager + void slotPartActivated( KParts::Part *part ); + + virtual void setIcon( const QPixmap& ); + void slotGoHistoryActivated( int steps ); + void slotGoHistoryActivated( int steps, Qt::ButtonState state ); + + void slotAddTab(); + void slotSplitViewHorizontal(); + void slotSplitViewVertical(); + +protected slots: + void slotViewCompleted( KonqView * view ); + + void slotURLEntered( const QString &text, int ); + + void slotFileNewAboutToShow(); + void slotLocationLabelActivated(); + + void slotDuplicateTab(); + void slotDuplicateTabPopup(); + + void slotBreakOffTab(); + void slotBreakOffTabPopup(); + void slotBreakOffTabPopupDelayed(); + + void slotPopupNewWindow(); + void slotPopupThisWindow(); + void slotPopupNewTab(); + void slotPopupNewTabRight(); + void slotPopupPasteTo(); + void slotRemoveView(); + + void slotRemoveOtherTabsPopup(); + void slotRemoveOtherTabsPopupDelayed(); + + void slotReloadPopup(); + void slotReloadAllTabs(); + void slotRemoveTab(); + void slotRemoveTabPopup(); + void slotRemoveTabPopupDelayed(); + + void slotActivateNextTab(); + void slotActivatePrevTab(); + void slotActivateTab(); + + void slotDumpDebugInfo(); + + void slotSaveViewProfile(); + void slotSaveViewPropertiesLocally(); + void slotRemoveLocalProperties(); + + void slotOpenEmbedded(); + void slotOpenEmbeddedDoIt(); + + // Connected to KSycoca + void slotDatabaseChanged(); + + // Connected to KApp + void slotReconfigure(); + + void slotForceSaveMainWindowSettings(); + + void slotOpenWith(); + + void slotGoMenuAboutToShow(); + void slotUpAboutToShow(); + void slotBackAboutToShow(); + void slotForwardAboutToShow(); + + void slotUpActivated( int id ); + void slotBackActivated( int id ); + void slotForwardActivated( int id ); + void slotGoHistoryDelayed(); + + void slotCompletionModeChanged( KGlobalSettings::Completion ); + void slotMakeCompletion( const QString& ); + void slotSubstringcompletion( const QString& ); + void slotRotation( KCompletionBase::KeyBindingType ); + void slotMatch( const QString& ); + void slotClearHistory(); + void slotClearComboHistory(); + + void slotClipboardDataChanged(); + void slotCheckComboSelection(); + + void slotShowMenuBar(); + + void slotOpenURL( const KURL& ); + + void slotActionStatusText( const QString &text ); + void slotClearStatusText(); + + void slotFindOpen( KonqDirPart * dirPart ); + void slotFindClosed( KonqDirPart * dirPart ); + + void slotIconsChanged(); + + virtual bool event( QEvent* ); + + void slotMoveTabLeft(); + void slotMoveTabRight(); + + void slotAddWebSideBar(const KURL& url, const QString& name); + + void slotUpdateFullScreen( bool set ); // do not call directly + +protected: + virtual bool eventFilter(QObject*obj,QEvent *ev); + + void fillHistoryPopup( QPopupMenu *menu, const QPtrList<HistoryEntry> &history ); + + bool makeViewsFollow( const KURL & url, const KParts::URLArgs &args, const QString & serviceType, + KonqView * senderView ); + + void applyKonqMainWindowSettings(); + + void saveToolBarServicesMap(); + + void viewsChanged(); + + void updateLocalPropsActions(); + + virtual void closeEvent( QCloseEvent * ); + virtual bool queryExit(); + + bool askForTarget(const QString& text, KURL& url); + +private slots: + void slotRequesterClicked( KURLRequester * ); + void slotIntro(); + void slotItemsRemoved( const KFileItemList & ); + /** + * Loads the url displayed currently in the lineedit of the locationbar, by + * emulating a enter key press event. + */ + void goURL(); + + void bookmarksIntoCompletion(); + + void initBookmarkBar(); + void slotTrashActivated( KAction::ActivationReason reason, Qt::ButtonState state ); + + void showPageSecurity(); + +private: + /** + * takes care of hiding the bookmarkbar and calling setChecked( false ) on the + * corresponding action + */ + void updateBookmarkBar(); + + /** + * Adds all children of @p group to the static completion object + */ + static void bookmarksIntoCompletion( const KBookmarkGroup& group ); + + /** + * Returns all matches of the url-history for @p s. If there are no direct + * matches, it will try completing with http:// prepended, and if there's + * still no match, then http://www. Due to that, this is only usable for + * popupcompletion and not for manual or auto-completion. + */ + static QStringList historyPopupCompletionItems( const QString& s = QString::null); + + void startAnimation(); + void stopAnimation(); + + void setUpEnabled( const KURL &url ); + + void initCombo(); + void initActions(); + + void popupNewTab(bool infront, bool openAfterCurrentPage); + + /** + * Tries to find a index.html (.kde.html) file in the specified directory + */ + static QString findIndexFile( const QString &directory ); + + void connectExtension( KParts::BrowserExtension *ext ); + void disconnectExtension( KParts::BrowserExtension *ext ); + + void plugViewModeActions(); + void unplugViewModeActions(); + static QString viewModeActionKey( KService::Ptr service ); + + void connectActionCollection( KActionCollection *coll ); + void disconnectActionCollection( KActionCollection *coll ); + + bool stayPreloaded(); + bool checkPreloadResourceUsage(); + + QObject* lastFrame( KonqView *view ); + + KNewMenu * m_pMenuNew; + + KAction *m_paPrint; + + KActionMenu *m_pamBookmarks; + + KToolBarPopupAction *m_paUp; + KToolBarPopupAction *m_paBack; + KToolBarPopupAction *m_paForward; + KAction *m_paHome; + + KonqBidiHistoryAction *m_paHistory; + + KAction *m_paSaveViewProfile; + KToggleAction *m_paSaveViewPropertiesLocally; + KAction *m_paRemoveLocalProperties; + + KAction *m_paSplitViewHor; + KAction *m_paSplitViewVer; + KAction *m_paAddTab; + KAction *m_paDuplicateTab; + KAction *m_paBreakOffTab; + KAction *m_paRemoveView; + KAction *m_paRemoveTab; + KAction *m_paRemoveOtherTabs; + KAction *m_paActivateNextTab; + KAction *m_paActivatePrevTab; + + KAction *m_paSaveRemoveViewProfile; + KActionMenu *m_pamLoadViewProfile; + + KToggleAction *m_paLockView; + KToggleAction *m_paLinkView; + KAction *m_paReload; + KAction *m_paReloadAllTabs; + KAction *m_paUndo; + KAction *m_paCut; + KAction *m_paCopy; + KAction *m_paPaste; + KAction *m_paStop; + KAction *m_paRename; + + KAction *m_paTrash; + KAction *m_paDelete; + + KAction *m_paCopyFiles; + KAction *m_paMoveFiles; + KAction *m_paNewDir; + + KAction *m_paMoveTabLeft; + KAction *m_paMoveTabRight; + + KAction *m_paConfigureExtensions; + KAction *m_paConfigureSpellChecking; + + KonqLogoAction *m_paAnimatedLogo; + + KBookmarkBar *m_paBookmarkBar; + + KToggleAction * m_paFindFiles; + KToggleAction *m_ptaUseHTML; + + KToggleAction *m_paShowMenuBar; + KToggleAction *m_paShowStatusBar; + + KToggleFullScreenAction *m_ptaFullScreen; + + uint m_bLocationBarConnected:1; + uint m_bURLEnterLock:1; + // Global settings + uint m_bSaveViewPropertiesLocally:1; + uint m_bHTMLAllowed:1; + // Set in constructor, used in slotRunFinished + uint m_bNeedApplyKonqMainWindowSettings:1; + uint m_bViewModeToggled:1; + + int m_goBuffer; + Qt::ButtonState m_goState; + + MapViews m_mapViews; + + QGuardedPtr<KonqView> m_currentView; + + KBookmarkMenu* m_pBookmarkMenu; + KonqExtendedBookmarkOwner *m_pBookmarksOwner; + KActionCollection* m_bookmarksActionCollection; + KActionCollection* m_bookmarkBarActionCollection; + + KonqViewManager *m_pViewManager; + KonqFrameBase* m_pChildFrame; + + KonqFrameBase* m_pWorkingTab; + + KFileItemList popupItems; + KParts::URLArgs popupUrlArgs; + + KonqRun *m_initialKonqRun; + + QString m_title; + + /** + * @since 3.4 + */ + KCMultiDialog* m_configureDialog; + + /** + * A list of the modules to be shown in + * the configure dialog. + * @since 3.4 + */ + QStringList m_configureModules; + + QLabel* m_locationLabel; + QGuardedPtr<KonqCombo> m_combo; + static KConfig *s_comboConfig; + KURLCompletion *m_pURLCompletion; + // just a reference to KonqHistoryManager's completionObject + static KCompletion *s_pCompletion; + + ToggleViewGUIClient *m_toggleViewGUIClient; + + KTrader::OfferList m_popupEmbeddingServices; + QString m_popupService; + QString m_popupServiceType; + KURL m_popupURL; + + QString m_initialFrameName; + + QPtrList<KAction> m_openWithActions; + KActionMenu *m_viewModeMenu; + QPtrList<KAction> m_toolBarViewModeActions; // basically holds two KonqViewActions, one of + // iconview and one for listview + QPtrList<KRadioAction> m_viewModeActions; + QMap<QString,KService::Ptr> m_viewModeToolBarServices; // similar to m_toolBarViewModeActions + // it holds a map library name (libkonqiconview/libkonqlistview) ==> service (service for + // iconview, multicolumnview, treeview, etc .) + + KonqMainWindowIface * m_dcopObject; + + static QStringList *s_plstAnimatedLogo; + + static QPtrList<KonqMainWindow> *s_lstViews; + + QString m_currentDir; // stores current dir for relative URLs whenever applicable + + bool m_urlCompletionStarted; + + bool m_prevMenuBarVisible; + + static bool s_preloaded; + static KonqMainWindow* s_preloadedWindow; + static int s_initialMemoryUsage; + static time_t s_startupTime; + static int s_preloadUsageCount; + +public: + + static QFile *s_crashlog_file; +}; + +#endif + diff --git a/konqueror/konq_mainwindow_p.h b/konqueror/konq_mainwindow_p.h new file mode 100644 index 000000000..74b5e6eed --- /dev/null +++ b/konqueror/konq_mainwindow_p.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Kellett <[email protected]> + Copyright (C) 1998, 1999 Simon Hausmann <[email protected]> + + 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 __konq_mainwindow_p_h__ +#define __konq_mainwindow_p_h__ + +class KonqExtendedBookmarkOwner : public KExtendedBookmarkOwner +{ + Q_OBJECT +public: + KonqExtendedBookmarkOwner(KonqMainWindow *); + // for KBookmarkOwner + virtual void openBookmarkURL( const QString & _url ); + virtual QString currentTitle() const; + virtual QString currentURL() const; +public slots: + // for KExtendedBookmarkOwner + void slotFillBookmarksList( KExtendedBookmarkOwner::QStringPairList & list ); +private: + KonqMainWindow *m_pKonqMainWindow; +}; + +#endif diff --git a/konqueror/konq_misc.cc b/konqueror/konq_misc.cc new file mode 100644 index 000000000..788462098 --- /dev/null +++ b/konqueror/konq_misc.cc @@ -0,0 +1,281 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 David Faure <[email protected]> + + 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 <qwhatsthis.h> +#include <qstyle.h> +#include <qdir.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kmessagebox.h> +#include <kurifilter.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kwin.h> +#include <kprotocolinfo.h> +#include <kurldrag.h> +#include <kstartupinfo.h> + +#include "konq_misc.h" +#include "konq_mainwindow.h" +#include "konq_viewmgr.h" +#include "konq_view.h" + +/********************************************** + * + * KonqMisc + * + **********************************************/ + +// Terminates fullscreen-mode for any full-screen window on the current desktop +void KonqMisc::abortFullScreenMode() +{ + QPtrList<KonqMainWindow> *mainWindows = KonqMainWindow::mainWindowList(); + if ( mainWindows ) + { + QPtrListIterator<KonqMainWindow> it( *mainWindows ); + for (; it.current(); ++it ) + { + if ( it.current()->fullScreenMode() ) + { + KWin::WindowInfo info = KWin::windowInfo( it.current()->winId(), NET::WMDesktop ); + if ( info.valid() && info.isOnCurrentDesktop() ) + it.current()->showNormal(); + } + } + } +} + +// #### this can probably be removed +KonqMainWindow * KonqMisc::createSimpleWindow( const KURL & _url, const QString &frameName ) +{ + abortFullScreenMode(); + + // If _url is 0L, open $HOME [this doesn't happen anymore] + KURL url; + if (_url.isEmpty()) + url.setPath(QDir::homeDirPath()); + else + url = _url; + + KonqMainWindow *win = new KonqMainWindow( KURL(), false ); + win->setInitialFrameName( frameName ); + win->openURL( 0L, url ); + win->show(); + + return win; +} + +KonqMainWindow * KonqMisc::createSimpleWindow( const KURL & url, const KParts::URLArgs &args, bool tempFile ) +{ + abortFullScreenMode(); + + KonqOpenURLRequest req; + req.args = args; + req.tempFile = tempFile; + KonqMainWindow *win = new KonqMainWindow( KURL(), false ); + win->openURL( 0L, url, QString::null, req ); + win->show(); + + return win; +} + +KonqMainWindow * KonqMisc::createNewWindow( const KURL &url, const KParts::URLArgs &args, bool forbidUseHTML, QStringList filesToSelect, bool tempFile, bool openURL ) +{ + kdDebug() << "KonqMisc::createNewWindow url=" << url << endl; + + // For HTTP or html files, use the web browsing profile, otherwise use filemanager profile + QString profileName = (!(KProtocolInfo::supportsListing(url)) || + KMimeType::findByURL(url)->name() == "text/html") + ? "webbrowsing" : "filemanagement"; + + QString profile = locate( "data", QString::fromLatin1("konqueror/profiles/") + profileName ); + return createBrowserWindowFromProfile(profile, profileName, + url, args, + forbidUseHTML, filesToSelect, tempFile, openURL ); +} + +KonqMainWindow * KonqMisc::createBrowserWindowFromProfile( const QString &path, const QString &filename, const KURL &url, const KParts::URLArgs &args, bool forbidUseHTML, const QStringList& filesToSelect, bool tempFile, bool openURL ) +{ + kdDebug(1202) << "void KonqMisc::createBrowserWindowFromProfile() " << endl; + kdDebug(1202) << "path=" << path << ",filename=" << filename << ",url=" << url.prettyURL() << endl; + abortFullScreenMode(); + + KonqMainWindow * mainWindow; + if ( path.isEmpty() ) + { + // The profile doesn't exit -> creating a simple window + mainWindow = createSimpleWindow( url, args, tempFile ); + if ( forbidUseHTML ) + mainWindow->setShowHTML( false ); + } + else if( KonqMainWindow::isPreloaded() && KonqMainWindow::preloadedWindow() != NULL ) + { + mainWindow = KonqMainWindow::preloadedWindow(); + KStartupInfo::setWindowStartupId( mainWindow->winId(), kapp->startupId()); + KonqMainWindow::setPreloadedWindow( NULL ); + KonqMainWindow::setPreloadedFlag( false ); + mainWindow->resetWindow(); + mainWindow->reparseConfiguration(); + if( forbidUseHTML ) + mainWindow->setShowHTML( false ); + KonqOpenURLRequest req; + req.args = args; + req.filesToSelect = filesToSelect; + req.tempFile = tempFile; + mainWindow->viewManager()->loadViewProfile( path, filename, url, req, true ); + } + else + { + KConfig cfg( path, true ); + cfg.setDollarExpansion( true ); + cfg.setGroup( "Profile" ); + QString xmluiFile=cfg.readEntry("XMLUIFile","konqueror.rc"); + + mainWindow = new KonqMainWindow( KURL(), false, 0, xmluiFile ); + if ( forbidUseHTML ) + mainWindow->setShowHTML( false ); + KonqOpenURLRequest req; + req.args = args; + req.filesToSelect = filesToSelect; + req.tempFile = tempFile; + mainWindow->viewManager()->loadViewProfile( cfg, filename, url, req, false, openURL ); + } + mainWindow->setInitialFrameName( args.frameName ); + mainWindow->show(); + return mainWindow; +} + +KonqMainWindow * KonqMisc::newWindowFromHistory( KonqView* view, int steps ) +{ + int oldPos = view->historyPos(); + int newPos = oldPos + steps; + + const HistoryEntry * he = view->historyAt(newPos); + if(!he) + return 0L; + + KonqMainWindow* mainwindow = createNewWindow(he->url, KParts::URLArgs(), + false, QStringList(), false, /*openURL*/false); + if(!mainwindow) + return 0L; + KonqView* newView = mainwindow->currentView(); + + if(!newView) + return 0L; + + newView->copyHistory(view); + newView->setHistoryPos(newPos); + newView->restoreHistory(); + return mainwindow; +} + +QString KonqMisc::konqFilteredURL( QWidget* parent, const QString& _url, const QString& _path ) +{ + if ( !_url.startsWith( "about:" ) ) // Don't filter "about:" URLs + { + KURIFilterData data = _url; + + if( !_path.isEmpty() ) + data.setAbsolutePath(_path); + + // We do not want to the filter to check for executables + // from the location bar. + data.setCheckForExecutables (false); + + if( KURIFilter::self()->filterURI( data ) ) + { + if( data.uriType() == KURIFilterData::ERROR && !data.errorMsg().isEmpty() ) + { + KMessageBox::sorry( parent, i18n( data.errorMsg().utf8() ) ); + return QString::null; + } + else + return data.uri().url(); + } + } + else if ( _url.startsWith( "about:" ) && _url != "about:blank" ) { + // We can't use "about:" as it is, KURL doesn't parse it. + if (_url == "about:plugins") + return "about:plugins"; + return "about:konqueror"; + } + return _url; // return the original url if it cannot be filtered. +} + +KonqDraggableLabel::KonqDraggableLabel( KonqMainWindow* mw, const QString& text ) + : QLabel( text, 0L, "kde toolbar widget" ) // Use this name for it to be styled! + , m_mw(mw) +{ + setBackgroundMode( Qt::PaletteButton ); + setAlignment( (QApplication::reverseLayout() ? Qt::AlignRight : Qt::AlignLeft) | + Qt::AlignVCenter | Qt::ShowPrefix ); + setAcceptDrops(true); + adjustSize(); + validDrag = false; +} + +void KonqDraggableLabel::mousePressEvent( QMouseEvent * ev ) +{ + validDrag = true; + startDragPos = ev->pos(); +} + +void KonqDraggableLabel::mouseMoveEvent( QMouseEvent * ev ) +{ + if ((startDragPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) + { + validDrag = false; + if ( m_mw->currentView() ) + { + KURL::List lst; + lst.append( m_mw->currentView()->url() ); + QDragObject * drag = new KURLDrag( lst, m_mw ); + drag->setPixmap( KMimeType::pixmapForURL( lst.first(), 0, KIcon::Small ) ); + drag->dragCopy(); + } + } +} + +void KonqDraggableLabel::mouseReleaseEvent( QMouseEvent * ) +{ + validDrag = false; +} + +void KonqDraggableLabel::dragEnterEvent( QDragEnterEvent *ev ) +{ + if ( KURLDrag::canDecode( ev ) ) + ev->acceptAction(); +} + +void KonqDraggableLabel::dropEvent( QDropEvent* ev ) +{ + _savedLst.clear(); + if ( KURLDrag::decode( ev, _savedLst ) ) { + QTimer::singleShot(0, this, SLOT(delayedOpenURL())); + } +} + +void KonqDraggableLabel::delayedOpenURL() +{ + m_mw->openURL( 0L, _savedLst.first() ); +} + +#include "konq_misc.moc" diff --git a/konqueror/konq_misc.h b/konqueror/konq_misc.h new file mode 100644 index 000000000..f3d736b13 --- /dev/null +++ b/konqueror/konq_misc.h @@ -0,0 +1,135 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 David Faure <[email protected]> + + 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 _konq_misc_h +#define _konq_misc_h + +// This file can hold every global class for konqueror that used to pollute +// konq_main.cc + +#include <krun.h> +#include <kparts/browserextension.h> +class KonqMainWindow; +class KonqView; + +class KonqMisc +{ +public: + /* + private: + static KonqFileManager *s_pSelf; + public: + KonqFileManager() {} + ~KonqFileManager() {} + + static KonqFileManager *self() + { + if ( !s_pSelf ) + s_pSelf = new KonqFileManager(); + return s_pSelf; + } + */ + + /** + * Stop full-screen mode in all windows. + */ + static void abortFullScreenMode(); + + /** + * Create a new window with a single view, showing @p url + */ + static KonqMainWindow * createSimpleWindow( const KURL &url, const QString &frameName = QString::null ); + + /** + * Create a new window with a single view, showing @p url, using @p args + */ + static KonqMainWindow * createSimpleWindow( const KURL &url, const KParts::URLArgs &args, + bool tempFile = false); + + /** + * Create a new window for @p url using @p args and the appropriate profile for this URL. + * @param forbidUseHTML internal. True when called by "Find Files" + * @param openURL If it is false, no url is openend in the new window. The url is used to guess the profile + */ + static KonqMainWindow * createNewWindow( const KURL &url, + const KParts::URLArgs &args = KParts::URLArgs(), + bool forbidUseHTML = false, + QStringList filesToSelect = QStringList(), + bool tempFile = false, + bool openURL = true); + + /** + * Create a new window from the profile defined by @p filename and @p path. + * @param url an optionnal URL to open in this profile. + * @param forbidUseHTML internal. True when called by "Find Files" + * @param openURL If false no url is opened + */ + static KonqMainWindow * createBrowserWindowFromProfile( const QString &path, + const QString &filename, + const KURL &url = KURL(), + const KParts::URLArgs &args = KParts::URLArgs(), + bool forbidUseHTML = false, + const QStringList& filesToSelect = QStringList(), + bool tempFile = false, + bool openURL = true); + + /** + * Creates a new window from the history of a view, copies the history + * @param view the History is copied from this view + * @param steps Restore currentPos() + steps + */ + static KonqMainWindow * newWindowFromHistory( KonqView* view, int steps ); + + /** + * Applies the URI filters to @p url. + * + * @p parent is used in case of a message box. + * @p _url to be filtered. + * @p _path the absolute path to append to the url before filtering it. + */ + static QString konqFilteredURL( QWidget* /*parent*/, const QString& /*_url*/, const QString& _path = QString::null ); + +}; + +#include <qlabel.h> + +class KonqDraggableLabel : public QLabel +{ + Q_OBJECT +public: + KonqDraggableLabel( KonqMainWindow * mw, const QString & text ); + +protected: + void mousePressEvent( QMouseEvent * ev ); + void mouseMoveEvent( QMouseEvent * ev ); + void mouseReleaseEvent( QMouseEvent * ); + void dragEnterEvent( QDragEnterEvent *ev ); + void dropEvent( QDropEvent* ev ); + +private slots: + void delayedOpenURL(); + +private: + QPoint startDragPos; + bool validDrag; + KonqMainWindow * m_mw; + KURL::List _savedLst; +}; + +#endif diff --git a/konqueror/konq_openurlrequest.h b/konqueror/konq_openurlrequest.h new file mode 100644 index 000000000..f3256c81f --- /dev/null +++ b/konqueror/konq_openurlrequest.h @@ -0,0 +1,64 @@ +#ifndef __konqopenurlrequest_h +#define __konqopenurlrequest_h + +#include <qstringlist.h> + +#include <kparts/browserextension.h> + +struct KonqOpenURLRequest { + + KonqOpenURLRequest() : + followMode(false), newTab(false), newTabInFront(false), + openAfterCurrentPage(false), forceAutoEmbed(false), + tempFile(false), userRequestedReload(false) {} + + KonqOpenURLRequest( const QString & url ) : + typedURL(url), followMode(false), newTab(false), newTabInFront(false), + openAfterCurrentPage(false), forceAutoEmbed(false), + tempFile(false), userRequestedReload(false) {} + + QString debug() const { +#ifndef NDEBUG + QStringList s; + if ( !args.frameName.isEmpty() ) + s << "frameName=" + args.frameName; + if ( !nameFilter.isEmpty() ) + s << "nameFilter=" + nameFilter; + if ( !typedURL.isEmpty() ) + s << "typedURL=" + typedURL; + if ( followMode ) + s << "followMode"; + if ( newTab ) + s << "newTab"; + if ( newTabInFront ) + s << "newTabInFront"; + if ( openAfterCurrentPage ) + s << "openAfterCurrentPage"; + if ( forceAutoEmbed ) + s << "forceAutoEmbed"; + if ( tempFile ) + s << "tempFile"; + if ( userRequestedReload ) + s << "userRequestedReload"; + return "[" + s.join(" ") + "]"; +#else + return QString::null; +#endif + } + + QString typedURL; // empty if URL wasn't typed manually + QString nameFilter; // like *.cpp, extracted from the URL + bool followMode; // true if following another view - avoids loops + bool newTab; // open url in new tab + bool newTabInFront; // new tab in front or back + bool openAfterCurrentPage; + bool forceAutoEmbed; // if true, override the user's FMSettings for embedding + bool tempFile; // if true, the url should be deleted after use + bool userRequestedReload; // args.reload because the user requested it, not a website + KParts::URLArgs args; + QStringList filesToSelect; // files to select in a konqdirpart + + static KonqOpenURLRequest null; +}; + +#endif diff --git a/konqueror/konq_profiledlg.cc b/konqueror/konq_profiledlg.cc new file mode 100644 index 000000000..a0e103a12 --- /dev/null +++ b/konqueror/konq_profiledlg.cc @@ -0,0 +1,266 @@ +/* This file is part of the KDE project + Copyright (C) 1999 Simon Hausmann <[email protected]> + + 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. + +*/ + +#include "konq_profiledlg.h" +#include "konq_viewmgr.h" +#include "konq_settingsxt.h" + +#include <qcheckbox.h> +#include <qdir.h> +#include <qvbox.h> +#include <qlabel.h> +#include <qheader.h> +#include <qlineedit.h> + +#include <klistview.h> +#include <kdebug.h> +#include <kstdguiitem.h> +#include <kio/global.h> +#include <kstandarddirs.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kseparator.h> +#include <kpushbutton.h> + +KonqProfileMap KonqProfileDlg::readAllProfiles() +{ + KonqProfileMap mapProfiles; + + QStringList profiles = KGlobal::dirs()->findAllResources( "data", "konqueror/profiles/*", false, true ); + QStringList::ConstIterator pIt = profiles.begin(); + QStringList::ConstIterator pEnd = profiles.end(); + for (; pIt != pEnd; ++pIt ) + { + QFileInfo info( *pIt ); + QString profileName = KIO::decodeFileName( info.baseName() ); + KSimpleConfig cfg( *pIt, true ); + if ( cfg.hasGroup( "Profile" ) ) + { + cfg.setGroup( "Profile" ); + if ( cfg.hasKey( "Name" ) ) + profileName = cfg.readEntry( "Name" ); + + mapProfiles.insert( profileName, *pIt ); + } + } + + return mapProfiles; +} + +KonqProfileItem::KonqProfileItem( KListView *parent, const QString & text ) + : QListViewItem( parent, text ), m_profileName( text ) +{ +} + +#define BTN_RENAME KDialogBase::User1 +#define BTN_DELETE KDialogBase::User2 +#define BTN_SAVE KDialogBase::User3 + +KonqProfileDlg::KonqProfileDlg( KonqViewManager *manager, const QString & preselectProfile, QWidget *parent ) +: KDialogBase( parent, "konq_profile_dialog", true, i18n( "Profile Management" ), + KDialogBase::Close | BTN_RENAME | BTN_DELETE | BTN_SAVE, BTN_SAVE, true, + KGuiItem( i18n( "&Rename Profile" ) ), + KGuiItem( i18n( "&Delete Profile" ), "editdelete"), + KStdGuiItem::save() ) +{ + m_pViewManager = manager; + + QVBox* box = new QVBox( this ); + box->setSpacing( KDialog::spacingHint() ); + setMainWidget( box ); + + QLabel *lblName = new QLabel( i18n( "&Profile name:" ), box ); + + m_pProfileNameLineEdit = new QLineEdit( box ); + m_pProfileNameLineEdit->setFocus(); + + lblName->setBuddy( m_pProfileNameLineEdit ); + + m_pListView = new KListView( box ); + m_pListView->setAllColumnsShowFocus(true); + m_pListView->header()->hide(); + m_pListView->addColumn(""); + m_pListView->setRenameable( 0 ); + + box->setStretchFactor( m_pListView, 1 ); + + connect( m_pListView, SIGNAL( itemRenamed( QListViewItem * ) ), + SLOT( slotItemRenamed( QListViewItem * ) ) ); + + loadAllProfiles( preselectProfile ); + m_pListView->setMinimumSize( m_pListView->sizeHint() ); + + m_cbSaveURLs = new QCheckBox( i18n("Save &URLs in profile"), box ); + m_cbSaveURLs->setChecked( KonqSettings::saveURLInProfile() ); + + m_cbSaveSize = new QCheckBox( i18n("Save &window size in profile"), box ); + m_cbSaveSize->setChecked( KonqSettings::saveWindowSizeInProfile() ); + + connect( m_pListView, SIGNAL( selectionChanged( QListViewItem * ) ), + this, SLOT( slotSelectionChanged( QListViewItem * ) ) ); + + connect( m_pProfileNameLineEdit, SIGNAL( textChanged( const QString & ) ), + this, SLOT( slotTextChanged( const QString & ) ) ); + + enableButton( BTN_RENAME, m_pListView->selectedItem ()!=0 ); + enableButton( BTN_DELETE, m_pListView->selectedItem ()!=0 ); + + resize( sizeHint() ); +} + +KonqProfileDlg::~KonqProfileDlg() +{ + KonqSettings::setSaveURLInProfile( m_cbSaveURLs->isChecked() ); + KonqSettings::setSaveWindowSizeInProfile( m_cbSaveSize->isChecked() ); +} + +void KonqProfileDlg::loadAllProfiles(const QString & preselectProfile) +{ + bool profileFound = false; + m_mapEntries.clear(); + m_pListView->clear(); + m_mapEntries = readAllProfiles(); + KonqProfileMap::ConstIterator eIt = m_mapEntries.begin(); + KonqProfileMap::ConstIterator eEnd = m_mapEntries.end(); + for (; eIt != eEnd; ++eIt ) + { + QListViewItem *item = new KonqProfileItem( m_pListView, eIt.key() ); + QString filename = eIt.data().mid( eIt.data().findRev( '/' ) + 1 ); + kdDebug(1202) << filename << endl; + if ( filename == preselectProfile ) + { + profileFound = true; + m_pProfileNameLineEdit->setText( eIt.key() ); + m_pListView->setSelected( item, true ); + } + } + if (!profileFound) + m_pProfileNameLineEdit->setText( preselectProfile); +} + +void KonqProfileDlg::slotUser3() // Save button +{ + QString name = KIO::encodeFileName( m_pProfileNameLineEdit->text() ); // in case of '/' + + // Reuse filename of existing item, if any + if ( m_pListView->selectedItem() ) + { + KonqProfileMap::Iterator it = m_mapEntries.find( m_pListView->selectedItem()->text(0) ); + if ( it != m_mapEntries.end() ) + { + QFileInfo info( it.data() ); + name = info.baseName(); + } + } + + kdDebug(1202) << "Saving as " << name << endl; + m_pViewManager->saveViewProfile( name, m_pProfileNameLineEdit->text(), + m_cbSaveURLs->isChecked(), m_cbSaveSize->isChecked() ); + + accept(); +} + +void KonqProfileDlg::slotUser2() // Delete button +{ + if(!m_pListView->selectedItem()) + return; + KonqProfileMap::Iterator it = m_mapEntries.find( m_pListView->selectedItem()->text(0) ); + + if ( it != m_mapEntries.end() && QFile::remove( it.data() ) ) + loadAllProfiles(); + + enableButton( BTN_RENAME, m_pListView->selectedItem() != 0 ); + enableButton( BTN_DELETE, m_pListView->selectedItem() != 0 ); +} + +void KonqProfileDlg::slotUser1() // Rename button +{ + QListViewItem *item = m_pListView->selectedItem(); + + if ( item ) + m_pListView->rename( item, 0 ); +} + +void KonqProfileDlg::slotItemRenamed( QListViewItem * item ) +{ + KonqProfileItem * profileItem = static_cast<KonqProfileItem *>( item ); + + QString newName = profileItem->text(0); + QString oldName = profileItem->m_profileName; + + if (!newName.isEmpty()) + { + KonqProfileMap::ConstIterator it = m_mapEntries.find( oldName ); + + if ( it != m_mapEntries.end() ) + { + QString fileName = it.data(); + KSimpleConfig cfg( fileName ); + cfg.setGroup( "Profile" ); + cfg.writeEntry( "Name", newName ); + cfg.sync(); + // Didn't find how to change a key... + m_mapEntries.remove( oldName ); + m_mapEntries.insert( newName, fileName ); + m_pProfileNameLineEdit->setText( newName ); + profileItem->m_profileName = newName; + } + } +} + +void KonqProfileDlg::slotSelectionChanged( QListViewItem * item ) +{ + m_pProfileNameLineEdit->setText( item ? item->text(0) : QString::null ); +} + +void KonqProfileDlg::slotTextChanged( const QString & text ) +{ + enableButton( KDialogBase::User3, !text.isEmpty() ); + + // If we type the name of a profile, select it in the list + + bool itemSelected = false; + QListViewItem * item; + + for ( item = m_pListView->firstChild() ; item ; item = item->nextSibling() ) + if ( item->text(0) == text /*only full text, not partial*/ ) + { + itemSelected = true; + m_pListView->setSelected( item, true ); + break; + } + + if ( !itemSelected ) // otherwise, clear selection + m_pListView->clearSelection(); + + if ( itemSelected ) + { + QFileInfo fi( m_mapEntries[ item->text( 0 ) ] ); + itemSelected = itemSelected && fi.isWritable(); + } + + enableButton( BTN_RENAME, itemSelected ); + enableButton( BTN_DELETE, itemSelected ); +} + +#undef BTN_RENAME +#undef BTN_DELETE +#undef BTN_SAVE + +#include "konq_profiledlg.moc" diff --git a/konqueror/konq_profiledlg.h b/konqueror/konq_profiledlg.h new file mode 100644 index 000000000..becb8e8fb --- /dev/null +++ b/konqueror/konq_profiledlg.h @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 1999 Simon Hausmann <[email protected]> + + 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_profiledlg_h__ +#define __konq_profiledlg_h__ + +#include <kdialogbase.h> + +#include <qlistview.h> +#include <qmap.h> + +class KonqViewManager; +class QListViewItem; +class QGridLayout; +class QCheckBox; +class QLineEdit; +class KPushButton; +class KListView; + +typedef QMap<QString, QString> KonqProfileMap; + +class KonqProfileItem : public QListViewItem +{ +public: + KonqProfileItem( KListView *, const QString & ); + ~KonqProfileItem() {} + + QString m_profileName; +}; + +class KonqProfileDlg : public KDialogBase +{ + Q_OBJECT +public: + KonqProfileDlg( KonqViewManager *manager, const QString &preselectProfile, QWidget *parent = 0L ); + ~KonqProfileDlg(); + + /** + * Find, read and return all available profiles + * @return a map with < name, full path > + */ + static KonqProfileMap readAllProfiles(); + +protected slots: + virtual void slotUser1(); // User1 is "Rename Profile" button + virtual void slotUser2(); // User2 is "Delete Profile" button + virtual void slotUser3(); // User3 is Save button + void slotTextChanged( const QString & ); + void slotSelectionChanged( QListViewItem * item ); + + void slotItemRenamed( QListViewItem * ); + +private: + void loadAllProfiles(const QString & = QString::null); + KonqViewManager *m_pViewManager; + + KonqProfileMap m_mapEntries; + + QLineEdit *m_pProfileNameLineEdit; + + QCheckBox *m_cbSaveURLs; + QCheckBox *m_cbSaveSize; + + KListView *m_pListView; +}; + +#endif diff --git a/konqueror/konq_run.cc b/konqueror/konq_run.cc new file mode 100644 index 000000000..96256f8c3 --- /dev/null +++ b/konqueror/konq_run.cc @@ -0,0 +1,195 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 <kdebug.h> + +#include "konq_run.h" +#include "konq_view.h" +#include <kuserprofile.h> +#include <kmessagebox.h> +#include <klocale.h> + +#include <konq_historymgr.h> + +#include <assert.h> + +#define HINT_UTF8 106 + +KonqRun::KonqRun( KonqMainWindow* mainWindow, KonqView *_childView, + const KURL & _url, const KonqOpenURLRequest & req, bool trustedSource ) + : KParts::BrowserRun( _url, req.args, _childView ? _childView->part() : 0L, mainWindow, + //remove referrer if request was typed in manually. + // ### TODO: turn this off optionally. + !req.typedURL.isEmpty(), trustedSource, + // Don't use inline errors on reloading due to auto-refresh sites, but use them in all other cases + // (no reload or user-requested reload) + !req.args.reload || req.userRequestedReload ), + m_pMainWindow( mainWindow ), m_pView( _childView ), m_bFoundMimeType( false ), m_req( req ) +{ + //kdDebug(1202) << "KonqRun::KonqRun() " << this << endl; + assert( !m_pMainWindow.isNull() ); + if (m_pView) + m_pView->setLoading(true); +} + +KonqRun::~KonqRun() +{ + //kdDebug(1202) << "KonqRun::~KonqRun() " << this << endl; + if (m_pView && m_pView->run() == this) + m_pView->setRun(0L); +} + +void KonqRun::foundMimeType( const QString & _type ) +{ + //kdDebug(1202) << "KonqRun::foundMimeType " << _type << " m_req=" << m_req.debug() << endl; + + QString mimeType = _type; // this ref comes from the job, we lose it when using KIO again + + m_bFoundMimeType = true; + + if (m_pView) + m_pView->setLoading(false); // first phase finished, don't confuse KonqView + + // Check if the main window wasn't deleted meanwhile + if( !m_pMainWindow ) + { + m_bFinished = true; + m_bFault = true; + m_timer.start( 0, true ); + return; + } + + // Grab the args back from BrowserRun + m_req.args = m_args; + + bool tryEmbed = true; + + // One case where we shouldn't try to embed, is when the server asks us to save + if ( serverSuggestsSave() ) + tryEmbed = false; + + if ( KonqMainWindow::isMimeTypeAssociatedWithSelf( mimeType ) ) + m_req.forceAutoEmbed = true; + + if ( tryEmbed ) + m_bFinished = m_pMainWindow->openView( mimeType, m_strURL, m_pView, m_req ); + + if ( m_bFinished ) { + m_pMainWindow = 0L; + m_timer.start( 0, true ); + return; + } + + // If we were following another view, do nothing if opening didn't work. + if ( m_req.followMode ) + m_bFinished = true; + + if ( !m_bFinished ) { + // If we couldn't embed the mimetype, call BrowserRun::handleNonEmbeddable() + KParts::BrowserRun::NonEmbeddableResult res = handleNonEmbeddable( mimeType ); + if ( res == KParts::BrowserRun::Delayed ) + return; + m_bFinished = ( res == KParts::BrowserRun::Handled ); + if (!m_bFinished && !tryEmbed) // Open selected for a serverSuggestsSave() file + m_bFinished = m_pMainWindow->openView( mimeType, m_strURL, m_pView, m_req ); + } + + // make Konqueror think there was an error, in order to stop the spinning wheel + // (we saved, canceled, or we're starting another app... in any case the current view should stop loading). + m_bFault = true; + + if ( !m_bFinished && // only if we're going to open + KonqMainWindow::isMimeTypeAssociatedWithSelf( mimeType ) ) { + KMessageBox::error( m_pMainWindow, i18n( "There appears to be a configuration error. You have associated Konqueror with %1, but it cannot handle this file type." ).arg( mimeType ) ); + m_bFinished = true; + } + + if ( m_bFinished ) { + m_pMainWindow = 0L; + m_timer.start( 0, true ); + return; + } + + kdDebug(1202) << "Nothing special to do in KonqRun, falling back to KRun" << endl; + KRun::foundMimeType( mimeType ); +} + +void KonqRun::handleError( KIO::Job *job ) +{ + kdDebug(1202) << "KonqRun::handleError error:" << job->errorString() << endl; + if (!m_mailto.isEmpty()) + { + m_job = 0; + m_bFinished = true; + m_timer.start( 0, true ); + return; + } + KParts::BrowserRun::handleError( job ); +} + +void KonqRun::init() +{ + KParts::BrowserRun::init(); + // Maybe init went to the "let's try stat'ing" part. Then connect to info messages. + // (in case it goes to scanFile, this will be done below) + KIO::StatJob *job = dynamic_cast<KIO::StatJob*>( m_job ); + if ( job && !job->error() && m_pView ) { + connect( job, SIGNAL( infoMessage( KIO::Job*, const QString& ) ), + m_pView, SLOT( slotInfoMessage(KIO::Job*, const QString& ) ) ); + } +} + +void KonqRun::scanFile() +{ + KParts::BrowserRun::scanFile(); + // could be a static cast as of now, but who would notify when + // BrowserRun changes + KIO::TransferJob *job = dynamic_cast<KIO::TransferJob*>( m_job ); + if ( job && !job->error() ) { + connect( job, SIGNAL( redirection( KIO::Job *, const KURL& )), + SLOT( slotRedirection( KIO::Job *, const KURL& ) )); + if ( m_pView && m_pView->service()->desktopEntryName() != "konq_sidebartng") { + connect( job, SIGNAL( infoMessage( KIO::Job*, const QString& ) ), + m_pView, SLOT( slotInfoMessage(KIO::Job*, const QString& ) ) ); + } + } +} + +void KonqRun::slotRedirection( KIO::Job *job, const KURL& redirectedToURL ) +{ + KURL redirectFromURL = static_cast<KIO::TransferJob *>(job)->url(); + kdDebug(1202) << "KonqRun::slotRedirection from " << + redirectFromURL.prettyURL() << " to " << redirectedToURL.prettyURL() << endl; + KonqHistoryManager::kself()->confirmPending( redirectFromURL ); + + if (redirectedToURL.protocol() == "mailto") + { + m_mailto = redirectedToURL; + return; // Error will follow + } + KonqHistoryManager::kself()->addPending( redirectedToURL ); + + // Do not post data on reload if we were redirected to a new URL when + // doing a POST request. + if (redirectFromURL != redirectedToURL) + m_args.setDoPost (false); + m_args.setRedirectedRequest(true); +} + +#include "konq_run.moc" diff --git a/konqueror/konq_run.h b/konqueror/konq_run.h new file mode 100644 index 000000000..50a393435 --- /dev/null +++ b/konqueror/konq_run.h @@ -0,0 +1,73 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 __kfm_run_h__ +#define __kfm_run_h__ + +#include <kparts/browserrun.h> +#include <qguardedptr.h> +#include <kservice.h> +#include "konq_openurlrequest.h" + +class KonqMainWindow; +class KonqView; + +class KonqRun : public KParts::BrowserRun +{ + Q_OBJECT +public: + /** + * Create a KonqRun instance, associated to the main view and an + * optionnal child view. + */ + KonqRun( KonqMainWindow* mainWindow, KonqView *childView, + const KURL &url, const KonqOpenURLRequest & req = KonqOpenURLRequest(), + bool trustedSource = false ); + + virtual ~KonqRun(); + + /** + * Returns true if we found the servicetype for the given url. + */ + bool foundMimeType() const { return m_bFoundMimeType; } + + KonqView *childView() const { return m_pView; } + + const QString & typedURL() const { return m_req.typedURL; } + + KURL mailtoURL() const { return m_mailto; } + +protected: + virtual void foundMimeType( const QString & _type ); + virtual void handleError( KIO::Job * job ); + virtual void init(); + virtual void scanFile(); + +protected slots: + void slotRedirection( KIO::Job *, const KURL& ); + +protected: + QGuardedPtr<KonqMainWindow> m_pMainWindow; + QGuardedPtr<KonqView> m_pView; + bool m_bFoundMimeType; + KonqOpenURLRequest m_req; + KURL m_mailto; +}; + +#endif diff --git a/konqueror/konq_settingsxt.kcfgc b/konqueror/konq_settingsxt.kcfgc new file mode 100644 index 000000000..a7c9a1063 --- /dev/null +++ b/konqueror/konq_settingsxt.kcfgc @@ -0,0 +1,4 @@ +File=konqueror.kcfg +ClassName=KonqSettings +Singleton=true +Mutators=true diff --git a/konqueror/konq_tabs.cc b/konqueror/konq_tabs.cc new file mode 100644 index 000000000..25af00bc8 --- /dev/null +++ b/konqueror/konq_tabs.cc @@ -0,0 +1,539 @@ +/* This file is part of the KDE project + + Copyright (C) 2002-2003 Konqueror Developers + 2002-2003 Douglas Hanley <[email protected]> + + 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. +*/ + +#include "konq_tabs.h" + +#include <qapplication.h> +#include <qclipboard.h> +#include <qptrlist.h> +#include <qpopupmenu.h> +#include <qtoolbutton.h> +#include <qtooltip.h> + +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kurldrag.h> +#include <kstringhandler.h> + +#include "konq_frame.h" +#include "konq_view.h" +#include "konq_viewmgr.h" +#include "konq_misc.h" +#include "konq_settingsxt.h" + +#include <kaccelmanager.h> +#include <konq_pixmapprovider.h> +#include <kstdaccel.h> +#include <qtabbar.h> +#include <qwhatsthis.h> +#include <qstyle.h> + +#define DUPLICATE_ID 3 +#define RELOAD_ID 4 +#define BREAKOFF_ID 5 +#define CLOSETAB_ID 6 +#define OTHERTABS_ID 7 + +//################################################################### + +KonqFrameTabs::KonqFrameTabs(QWidget* parent, KonqFrameContainerBase* parentContainer, + KonqViewManager* viewManager, const char * name) + : KTabWidget(parent, name), m_rightWidget(0), m_leftWidget(0), m_alwaysTabBar(false), + m_closeOtherTabsId(0) +{ + KAcceleratorManager::setNoAccel(this); + + QWhatsThis::add( tabBar(), i18n( "This bar contains the list of currently open tabs. Click on a tab to make it " + "active. The option to show a close button instead of the website icon in the left " + "corner of the tab is configurable. You can also use keyboard shortcuts to " + "navigate through tabs. The text on the tab is the title of the website " + "currently open in it, put your mouse over the tab too see the full title in " + "case it was truncated to fit the tab size." ) ); + //kdDebug(1202) << "KonqFrameTabs::KonqFrameTabs()" << endl; + + m_pParentContainer = parentContainer; + m_pChildFrameList = new QPtrList<KonqFrameBase>; + m_pChildFrameList->setAutoDelete(false); + m_pActiveChild = 0L; + m_pViewManager = viewManager; + + connect( this, SIGNAL( currentChanged ( QWidget * ) ), + this, SLOT( slotCurrentChanged( QWidget* ) ) ); + + m_pPopupMenu = new QPopupMenu( this ); + m_pPopupMenu->insertItem( SmallIcon( "tab_new" ), + i18n("&New Tab"), + m_pViewManager->mainWindow(), + SLOT( slotAddTab() ), + m_pViewManager->mainWindow()->action("newtab")->shortcut() ); + m_pPopupMenu->insertItem( SmallIconSet( "reload" ), + i18n( "&Reload Tab" ), + m_pViewManager->mainWindow(), + SLOT( slotReloadPopup() ), + m_pViewManager->mainWindow()->action("reload")->shortcut(), RELOAD_ID ); + m_pPopupMenu->insertItem( SmallIconSet( "tab_duplicate" ), + i18n("&Duplicate Tab"), + m_pViewManager->mainWindow(), + SLOT( slotDuplicateTabPopup() ), + m_pViewManager->mainWindow()->action("duplicatecurrenttab")->shortcut(), + DUPLICATE_ID ); + m_pPopupMenu->insertItem( SmallIconSet( "tab_breakoff" ), + i18n("D&etach Tab"), + m_pViewManager->mainWindow(), + SLOT( slotBreakOffTabPopup() ), + m_pViewManager->mainWindow()->action("breakoffcurrenttab")->shortcut(), + BREAKOFF_ID ); + m_pPopupMenu->insertSeparator(); + m_pSubPopupMenuTab = new QPopupMenu( this ); + m_pPopupMenu->insertItem( i18n("Other Tabs" ), m_pSubPopupMenuTab, OTHERTABS_ID ); + connect( m_pSubPopupMenuTab, SIGNAL( activated ( int ) ), + this, SLOT( slotSubPopupMenuTabActivated( int ) ) ); + m_pPopupMenu->insertSeparator(); + m_pPopupMenu->insertItem( SmallIconSet( "tab_remove" ), + i18n("&Close Tab"), + m_pViewManager->mainWindow(), + SLOT( slotRemoveTabPopup() ), + m_pViewManager->mainWindow()->action("removecurrenttab")->shortcut(), + CLOSETAB_ID ); + connect( this, SIGNAL( contextMenu( QWidget *, const QPoint & ) ), + SLOT(slotContextMenu( QWidget *, const QPoint & ) ) ); + connect( this, SIGNAL( contextMenu( const QPoint & ) ), + SLOT(slotContextMenu( const QPoint & ) ) ); + + m_MouseMiddleClickClosesTab = KonqSettings::mouseMiddleClickClosesTab(); + + m_permanentCloseButtons = KonqSettings::permanentCloseButton(); + if (m_permanentCloseButtons) { + setHoverCloseButton( true ); + setHoverCloseButtonDelayed( false ); + } + else + setHoverCloseButton( KonqSettings::hoverCloseButton() ); + setTabCloseActivatePrevious( KonqSettings::tabCloseActivatePrevious() ); + if (KonqSettings::tabPosition()=="Bottom") + setTabPosition(QTabWidget::Bottom); + connect( this, SIGNAL( closeRequest( QWidget * )), SLOT(slotCloseRequest( QWidget * ))); + connect( this, SIGNAL( removeTabPopup() ), + m_pViewManager->mainWindow(), SLOT( slotRemoveTabPopup() ) ); + + if ( KonqSettings::addTabButton() ) { + m_leftWidget = new QToolButton( this ); + connect( m_leftWidget, SIGNAL( clicked() ), + m_pViewManager->mainWindow(), SLOT( slotAddTab() ) ); + m_leftWidget->setIconSet( SmallIcon( "tab_new" ) ); + m_leftWidget->adjustSize(); + QToolTip::add(m_leftWidget, i18n("Open a new tab")); + setCornerWidget( m_leftWidget, TopLeft ); + } + if ( KonqSettings::closeTabButton() ) { + m_rightWidget = new QToolButton( this ); + connect( m_rightWidget, SIGNAL( clicked() ), + m_pViewManager->mainWindow(), SLOT( slotRemoveTab() ) ); + m_rightWidget->setIconSet( SmallIconSet( "tab_remove" ) ); + m_rightWidget->adjustSize(); + QToolTip::add(m_rightWidget, i18n("Close the current tab")); + setCornerWidget( m_rightWidget, TopRight ); + } + + setAutomaticResizeTabs( true ); + setTabReorderingEnabled( true ); + connect( this, SIGNAL( movedTab( int, int ) ), + SLOT( slotMovedTab( int, int ) ) ); + connect( this, SIGNAL( mouseMiddleClick() ), + SLOT( slotMouseMiddleClick() ) ); + connect( this, SIGNAL( mouseMiddleClick( QWidget * ) ), + SLOT( slotMouseMiddleClick( QWidget * ) ) ); + connect( this, SIGNAL( mouseDoubleClick() ), + m_pViewManager->mainWindow(), SLOT( slotAddTab() ) ); + + connect( this, SIGNAL( testCanDecode(const QDragMoveEvent *, bool & )), + SLOT( slotTestCanDecode(const QDragMoveEvent *, bool & ) ) ); + connect( this, SIGNAL( receivedDropEvent( QDropEvent * )), + SLOT( slotReceivedDropEvent( QDropEvent * ) ) ); + connect( this, SIGNAL( receivedDropEvent( QWidget *, QDropEvent * )), + SLOT( slotReceivedDropEvent( QWidget *, QDropEvent * ) ) ); + connect( this, SIGNAL( initiateDrag( QWidget * )), + SLOT( slotInitiateDrag( QWidget * ) ) ); +} + +KonqFrameTabs::~KonqFrameTabs() +{ + //kdDebug(1202) << "KonqFrameTabs::~KonqFrameTabs() " << this << " - " << className() << endl; + m_pChildFrameList->setAutoDelete(true); + delete m_pChildFrameList; +} + +void KonqFrameTabs::listViews( ChildViewList *viewList ) { + for( QPtrListIterator<KonqFrameBase> it( *m_pChildFrameList ); *it; ++it ) + it.current()->listViews(viewList); +} + +void KonqFrameTabs::saveConfig( KConfig* config, const QString &prefix, bool saveURLs, + KonqFrameBase* docContainer, int id, int depth ) +{ + //write children + QStringList strlst; + int i = 0; + QString newPrefix; + for (KonqFrameBase* it = m_pChildFrameList->first(); it; it = m_pChildFrameList->next()) + { + newPrefix = QString::fromLatin1( it->frameType() ) + "T" + QString::number(i); + strlst.append( newPrefix ); + newPrefix.append( '_' ); + it->saveConfig( config, newPrefix, saveURLs, docContainer, id, depth + i ); + i++; + } + + config->writeEntry( QString::fromLatin1( "Children" ).prepend( prefix ), strlst ); + + config->writeEntry( QString::fromLatin1( "activeChildIndex" ).prepend( prefix ), + currentPageIndex() ); +} + +void KonqFrameTabs::copyHistory( KonqFrameBase *other ) +{ + if( other->frameType() != "Tabs" ) { + kdDebug(1202) << "Frame types are not the same" << endl; + return; + } + + for (uint i = 0; i < m_pChildFrameList->count(); i++ ) + { + m_pChildFrameList->at(i)->copyHistory( static_cast<KonqFrameTabs *>( other )->m_pChildFrameList->at(i) ); + } +} + +void KonqFrameTabs::printFrameInfo( const QString& spaces ) +{ + kdDebug(1202) << spaces << "KonqFrameTabs " << this << " visible=" + << QString("%1").arg(isVisible()) << " activeChild=" + << m_pActiveChild << endl; + + if (!m_pActiveChild) + kdDebug(1202) << "WARNING: " << this << " has a null active child!" << endl; + + KonqFrameBase* child; + int childFrameCount = m_pChildFrameList->count(); + for (int i = 0 ; i < childFrameCount ; i++) { + child = m_pChildFrameList->at(i); + if (child != 0L) + child->printFrameInfo(spaces + " "); + else + kdDebug(1202) << spaces << " Null child" << endl; + } +} + +void KonqFrameTabs::reparentFrame( QWidget* parent, const QPoint & p, bool showIt ) +{ + QWidget::reparent( parent, p, showIt ); +} + +void KonqFrameTabs::setTitle( const QString &title , QWidget* sender) +{ + // kdDebug(1202) << "KonqFrameTabs::setTitle( " << title << " , " << sender << " )" << endl; + setTabLabel( sender,title ); +} + +void KonqFrameTabs::setTabIcon( const KURL &url, QWidget* sender ) +{ + //kdDebug(1202) << "KonqFrameTabs::setTabIcon( " << url << " , " << sender << " )" << endl; + QIconSet iconSet; + if (m_permanentCloseButtons) + iconSet = SmallIcon( "fileclose" ); + else + iconSet = SmallIconSet( KonqPixmapProvider::self()->iconNameFor( url.url() ) ); + if (tabIconSet( sender ).pixmap().serialNumber() != iconSet.pixmap().serialNumber()) + setTabIconSet( sender, iconSet ); +} + +void KonqFrameTabs::activateChild() +{ + if (m_pActiveChild) + { + showPage( m_pActiveChild->widget() ); + m_pActiveChild->activateChild(); + } +} + +void KonqFrameTabs::insertChildFrame( KonqFrameBase* frame, int index ) +{ + //kdDebug(1202) << "KonqFrameTabs " << this << ": insertChildFrame " << frame << endl; + + if (frame) + { + //kdDebug(1202) << "Adding frame" << endl; + bool showTabBar = (count() == 1); + insertTab(frame->widget(),"", index); + frame->setParentContainer(this); + if (index == -1) m_pChildFrameList->append(frame); + else m_pChildFrameList->insert(index, frame); + if (m_rightWidget) + m_rightWidget->setEnabled( m_pChildFrameList->count()>1 ); + KonqView* activeChildView = frame->activeChildView(); + if (activeChildView != 0L) { + activeChildView->setCaption( activeChildView->caption() ); + activeChildView->setTabIcon( activeChildView->url() ); + } + if (showTabBar) + setTabBarHidden(false); + else if ( count() == 1 ) + this->hideTabBar();//the first frame inserted (initialization) + } + else + kdWarning(1202) << "KonqFrameTabs " << this << ": insertChildFrame(0L) !" << endl; +} + +void KonqFrameTabs::removeChildFrame( KonqFrameBase * frame ) +{ + //kdDebug(1202) << "KonqFrameTabs::RemoveChildFrame " << this << ". Child " << frame << " removed" << endl; + if (frame) { + removePage(frame->widget()); + m_pChildFrameList->remove(frame); + if (m_rightWidget) + m_rightWidget->setEnabled( m_pChildFrameList->count()>1 ); + if (count() == 1) + hideTabBar(); + } + else + kdWarning(1202) << "KonqFrameTabs " << this << ": removeChildFrame(0L) !" << endl; + + //kdDebug(1202) << "KonqFrameTabs::RemoveChildFrame finished" << endl; +} + +void KonqFrameTabs::slotCurrentChanged( QWidget* newPage ) +{ + setTabColor( newPage, KGlobalSettings::textColor() ); + KonqFrameBase* currentFrame = dynamic_cast<KonqFrameBase*>(newPage); + + if (currentFrame && !m_pViewManager->isLoadingProfile()) { + m_pActiveChild = currentFrame; + currentFrame->activateChild(); + } +} + +void KonqFrameTabs::moveTabBackward( int index ) +{ + if ( index == 0 ) + return; + moveTab( index, index-1 ); +} + +void KonqFrameTabs::moveTabForward( int index ) +{ + if ( index == count()-1 ) + return; + moveTab( index, index+1 ); +} + +void KonqFrameTabs::slotMovedTab( int from, int to ) +{ + KonqFrameBase* fromFrame = m_pChildFrameList->at( from ); + m_pChildFrameList->remove( fromFrame ); + m_pChildFrameList->insert( to, fromFrame ); + + KonqFrameBase* currentFrame = dynamic_cast<KonqFrameBase*>( currentPage() ); + if ( currentFrame && !m_pViewManager->isLoadingProfile() ) { + m_pActiveChild = currentFrame; + currentFrame->activateChild(); + } +} + +void KonqFrameTabs::slotContextMenu( const QPoint &p ) +{ + refreshSubPopupMenuTab(); + + m_pPopupMenu->setItemEnabled( RELOAD_ID, false ); + m_pPopupMenu->setItemEnabled( DUPLICATE_ID, false ); + m_pPopupMenu->setItemEnabled( BREAKOFF_ID, false ); + m_pPopupMenu->setItemEnabled( CLOSETAB_ID, false ); + m_pPopupMenu->setItemEnabled( OTHERTABS_ID, true ); + m_pSubPopupMenuTab->setItemEnabled( m_closeOtherTabsId, false ); + + m_pPopupMenu->exec( p ); +} + +void KonqFrameTabs::slotContextMenu( QWidget *w, const QPoint &p ) +{ + refreshSubPopupMenuTab(); + + uint tabCount = m_pChildFrameList->count(); + m_pPopupMenu->setItemEnabled( RELOAD_ID, true ); + m_pPopupMenu->setItemEnabled( DUPLICATE_ID, true ); + m_pPopupMenu->setItemEnabled( BREAKOFF_ID, tabCount>1 ); + m_pPopupMenu->setItemEnabled( CLOSETAB_ID, tabCount>1 ); + m_pPopupMenu->setItemEnabled( OTHERTABS_ID, tabCount>1 ); + m_pSubPopupMenuTab->setItemEnabled( m_closeOtherTabsId, true ); + + // Yes, I know this is an unchecked dynamic_cast - I'm casting sideways in a + // class hierarchy and it could crash one day, but I haven't checked + // setWorkingTab so I don't know if it can handle nulls. + + m_pViewManager->mainWindow()->setWorkingTab( dynamic_cast<KonqFrameBase*>(w) ); + m_pPopupMenu->exec( p ); +} + +void KonqFrameTabs::refreshSubPopupMenuTab() +{ + m_pSubPopupMenuTab->clear(); + int i=0; + m_pSubPopupMenuTab->insertItem( SmallIcon( "reload_all_tabs" ), + i18n( "&Reload All Tabs" ), + m_pViewManager->mainWindow(), + SLOT( slotReloadAllTabs() ), + m_pViewManager->mainWindow()->action("reload_all_tabs")->shortcut() ); + m_pSubPopupMenuTab->insertSeparator(); + for (KonqFrameBase* it = m_pChildFrameList->first(); it; it = m_pChildFrameList->next()) + { + KonqFrame* frame = dynamic_cast<KonqFrame *>(it); + if ( frame && frame->activeChildView() ) + { + QString title = frame->title().stripWhiteSpace(); + if ( title.isEmpty() ) + title = frame->activeChildView()->url().url(); + title = KStringHandler::csqueeze( title, 50 ); + m_pSubPopupMenuTab->insertItem( QIconSet( KonqPixmapProvider::self()->pixmapFor( frame->activeChildView()->url().url() ) ), title, i ); + + } + i++; + } + m_pSubPopupMenuTab->insertSeparator(); + m_closeOtherTabsId = + m_pSubPopupMenuTab->insertItem( SmallIconSet( "tab_remove_other" ), + i18n( "Close &Other Tabs" ), + m_pViewManager->mainWindow(), + SLOT( slotRemoveOtherTabsPopup() ), + m_pViewManager->mainWindow()->action("removeothertabs")->shortcut() ); +} + +void KonqFrameTabs::slotCloseRequest( QWidget *w ) +{ + if ( m_pChildFrameList->count() > 1 ) { + // Yes, I know this is an unchecked dynamic_cast - I'm casting sideways in a class hierarchy and it could crash one day, but I haven't checked setWorkingTab so I don't know if it can handle nulls. + m_pViewManager->mainWindow()->setWorkingTab( dynamic_cast<KonqFrameBase*>(w) ); + emit ( removeTabPopup() ); + } +} + +void KonqFrameTabs::slotSubPopupMenuTabActivated( int _id) +{ + setCurrentPage( _id ); +} + +void KonqFrameTabs::slotMouseMiddleClick() +{ + QApplication::clipboard()->setSelectionMode( QClipboard::Selection ); + KURL filteredURL ( KonqMisc::konqFilteredURL( this, QApplication::clipboard()->text() ) ); + if ( !filteredURL.isEmpty() ) { + KonqView* newView = m_pViewManager->addTab(QString::null, QString::null, false, false); + if (newView == 0L) return; + m_pViewManager->mainWindow()->openURL( newView, filteredURL, QString::null ); + m_pViewManager->showTab( newView ); + m_pViewManager->mainWindow()->focusLocationBar(); + } +} + +void KonqFrameTabs::slotMouseMiddleClick( QWidget *w ) +{ + if ( m_MouseMiddleClickClosesTab ) { + if ( m_pChildFrameList->count() > 1 ) { + // Yes, I know this is an unchecked dynamic_cast - I'm casting sideways in a class hierarchy and it could crash one day, but I haven't checked setWorkingTab so I don't know if it can handle nulls. + m_pViewManager->mainWindow()->setWorkingTab( dynamic_cast<KonqFrameBase*>(w) ); + emit ( removeTabPopup() ); + } + } + else { + QApplication::clipboard()->setSelectionMode( QClipboard::Selection ); + KURL filteredURL ( KonqMisc::konqFilteredURL( this, QApplication::clipboard()->text() ) ); + if ( !filteredURL.isEmpty() ) { + KonqFrameBase* frame = dynamic_cast<KonqFrameBase*>(w); + if (frame) { + m_pViewManager->mainWindow()->openURL( frame->activeChildView(), filteredURL ); + } + } + } +} + +void KonqFrameTabs::slotTestCanDecode(const QDragMoveEvent *e, bool &accept /* result */) +{ + accept = KURLDrag::canDecode( e ); +} + +void KonqFrameTabs::slotReceivedDropEvent( QDropEvent *e ) +{ + KURL::List lstDragURLs; + bool ok = KURLDrag::decode( e, lstDragURLs ); + if ( ok && lstDragURLs.first().isValid() ) { + KonqView* newView = m_pViewManager->addTab(QString::null, QString::null, false, false); + if (newView == 0L) return; + m_pViewManager->mainWindow()->openURL( newView, lstDragURLs.first(), QString::null ); + m_pViewManager->showTab( newView ); + m_pViewManager->mainWindow()->focusLocationBar(); + } +} + +void KonqFrameTabs::slotReceivedDropEvent( QWidget *w, QDropEvent *e ) +{ + KURL::List lstDragURLs; + bool ok = KURLDrag::decode( e, lstDragURLs ); + KonqFrameBase* frame = dynamic_cast<KonqFrameBase*>(w); + if ( ok && lstDragURLs.first().isValid() && frame ) { + KURL lstDragURL = lstDragURLs.first(); + if ( lstDragURL != frame->activeChildView()->url() ) + m_pViewManager->mainWindow()->openURL( frame->activeChildView(), lstDragURL ); + } +} + +void KonqFrameTabs::slotInitiateDrag( QWidget *w ) +{ + KonqFrameBase* frame = dynamic_cast<KonqFrameBase*>( w ); + if (frame) { + KURL::List lst; + lst.append( frame->activeChildView()->url() ); + KURLDrag *d = new KURLDrag( lst, this ); + d->setPixmap( KMimeType::pixmapForURL( lst.first(), 0, KIcon::Small ) ); + d->dragCopy(); + } +} + +void KonqFrameTabs::hideTabBar() +{ + if ( !m_alwaysTabBar ) { + setTabBarHidden(true); + } + m_pPopupMenu->setItemEnabled( BREAKOFF_ID, false ); + m_pPopupMenu->setItemEnabled( CLOSETAB_ID, false ); +} + +void KonqFrameTabs::setAlwaysTabbedMode( bool enable ) +{ + bool update = ( enable != m_alwaysTabBar ); + + m_alwaysTabBar = enable; + if ( update ) { + if ( m_alwaysTabBar ) + setTabBarHidden(false); + else + hideTabBar(); + } +} + +#include "konq_tabs.moc" diff --git a/konqueror/konq_tabs.h b/konqueror/konq_tabs.h new file mode 100644 index 000000000..98060e0bb --- /dev/null +++ b/konqueror/konq_tabs.h @@ -0,0 +1,130 @@ +/* This file is part of the KDE project + + Copyright (C) 2002-2003 Konqueror Developers + 2002-2003 Douglas Hanley <[email protected]> + + 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_tabs_h__ +#define __konq_tabs_h__ + +#include "konq_frame.h" + +#include <ktabwidget.h> + +class QPixmap; +class QPopupMenu; +class QToolButton; + +class KonqView; +class KonqViewManager; +class KonqFrameBase; +class KonqFrame; +class KonqFrameContainerBase; +class KonqFrameContainer; +class KConfig; +class KSeparator; +class KProgress; +class KAction; + +class KonqFrameTabs : public KTabWidget, public KonqFrameContainerBase +{ + Q_OBJECT + friend class KonqFrame; //for emitting ctrlTabPressed() only, aleXXX + +public: + KonqFrameTabs(QWidget* parent, KonqFrameContainerBase* parentContainer, + KonqViewManager* viewManager, const char * name = 0); + virtual ~KonqFrameTabs(); + + virtual void listViews( ChildViewList *viewList ); + + virtual void saveConfig( KConfig* config, const QString &prefix, bool saveURLs, + KonqFrameBase* docContainer, int id = 0, int depth = 0 ); + virtual void copyHistory( KonqFrameBase *other ); + + virtual void printFrameInfo( const QString& spaces ); + + QPtrList<KonqFrameBase>* childFrameList() { return m_pChildFrameList; } + + virtual void setTitle( const QString &title, QWidget* sender ); + virtual void setTabIcon( const KURL &url, QWidget* sender ); + + virtual QWidget* widget() { return this; } + virtual QCString frameType() { return QCString("Tabs"); } + + void activateChild(); + + /** + * Call this after inserting a new frame into the splitter. + */ + void insertChildFrame( KonqFrameBase * frame, int index = -1); + + /** + * Call this before deleting one of our children. + */ + void removeChildFrame( KonqFrameBase * frame ); + + //inherited + virtual void reparentFrame(QWidget * parent, + const QPoint & p, bool showIt=FALSE ); + + void moveTabBackward(int index); + void moveTabForward(int index); + + +public slots: + void slotCurrentChanged( QWidget* newPage ); + void setAlwaysTabbedMode( bool ); + +signals: + void ctrlTabPressed(); + void removeTabPopup(); + +protected: + void refreshSubPopupMenuTab(); + void hideTabBar(); + + QPtrList<KonqFrameBase>* m_pChildFrameList; + +private slots: + void slotContextMenu( const QPoint& ); + void slotContextMenu( QWidget*, const QPoint& ); + void slotCloseRequest( QWidget* ); + void slotMovedTab( int, int ); + void slotMouseMiddleClick(); + void slotMouseMiddleClick( QWidget* ); + + void slotTestCanDecode(const QDragMoveEvent *e, bool &accept /* result */); + void slotReceivedDropEvent( QDropEvent* ); + void slotInitiateDrag( QWidget * ); + void slotReceivedDropEvent( QWidget *, QDropEvent * ); + void slotSubPopupMenuTabActivated( int ); + +private: + KonqViewManager* m_pViewManager; + QPopupMenu* m_pPopupMenu; + QPopupMenu* m_pSubPopupMenuTab; + QToolButton* m_rightWidget; + QToolButton* m_leftWidget; + bool m_permanentCloseButtons; + bool m_alwaysTabBar; + bool m_MouseMiddleClickClosesTab; + int m_closeOtherTabsId; +}; + +#endif diff --git a/konqueror/konq_view.cc b/konqueror/konq_view.cc new file mode 100644 index 000000000..87222734c --- /dev/null +++ b/konqueror/konq_view.cc @@ -0,0 +1,1398 @@ +/* -*- c-basic-offset: 2 -*- + This file is part of the KDE project + Copyright (C) 1998-2005 David Faure <[email protected]> + + 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_view.h" +#include "kapplication.h" +#include "KonqViewIface.h" +#include "konq_settingsxt.h" +#include "konq_frame.h" +#include "konq_run.h" +#include "konq_events.h" +#include "konq_viewmgr.h" +#include "konq_tabs.h" +#include "konq_browseriface.h" +#include <kparts/statusbarextension.h> +#include <kparts/browserextension.h> + +#include <konq_historymgr.h> +#include <konq_pixmapprovider.h> + +#include <assert.h> +#include <kdebug.h> +#include <kcursor.h> +#include <kurldrag.h> +#include <qscrollview.h> + +#include <qapplication.h> +#include <qmetaobject.h> +#include <qobjectlist.h> +#include <config.h> +#include <private/qucomextra_p.h> +#include <kmessagebox.h> +#include <klocale.h> + +#include <fixx11h.h> + +//#define DEBUG_HISTORY + +template class QPtrList<HistoryEntry>; + +KonqView::KonqView( KonqViewFactory &viewFactory, + KonqFrame* viewFrame, + KonqMainWindow *mainWindow, + const KService::Ptr &service, + const KTrader::OfferList &partServiceOffers, + const KTrader::OfferList &appServiceOffers, + const QString &serviceType, + bool passiveMode + ) +{ + m_pKonqFrame = viewFrame; + m_pKonqFrame->setView( this ); + + m_sLocationBarURL = ""; + m_pageSecurity = KonqMainWindow::NotCrypted; + m_bLockHistory = false; + m_doPost = false; + m_pMainWindow = mainWindow; + m_pRun = 0L; + m_pPart = 0L; + m_dcopObject = 0L; + + m_randID = KApplication::random(); + + m_service = service; + m_partServiceOffers = partServiceOffers; + m_appServiceOffers = appServiceOffers; + m_serviceType = serviceType; + + m_bAllowHTML = m_pMainWindow->isHTMLAllowed(); + m_lstHistory.setAutoDelete( true ); + m_bLoading = false; + m_bPendingRedirection = false; + m_bPassiveMode = passiveMode; + m_bLockedLocation = false; + m_bLinkedView = false; + m_bAborted = false; + m_bToggleView = false; + m_bHierarchicalView = false; + m_bDisableScrolling = false; + m_bGotIconURL = false; + m_bPopupMenuEnabled = true; + m_browserIface = new KonqBrowserInterface( this, "browseriface" ); + m_bBackRightClick = KonqSettings::backRightClick(); + m_bFollowActive = false; + m_bBuiltinView = false; + m_bURLDropHandling = false; + + switchView( viewFactory ); +} + +KonqView::~KonqView() +{ + //kdDebug(1202) << "KonqView::~KonqView : part = " << m_pPart << endl; + + if (KonqMainWindow::s_crashlog_file) { + QString part_url; + if (m_pPart) + part_url = m_pPart->url().url(); + if (part_url.isNull()) + part_url = ""; + QCString line; + line = ( QString("close(%1):%2\n").arg(m_randID,0,16).arg(part_url) ).utf8(); + KonqMainWindow::s_crashlog_file->writeBlock(line, line.length()); + KonqMainWindow::s_crashlog_file->flush(); + } + + // We did so ourselves for passive views + if (m_pPart != 0L) + { + finishedWithCurrentURL(); + if ( isPassiveMode() ) + disconnect( m_pPart, SIGNAL( destroyed() ), m_pMainWindow->viewManager(), SLOT( slotObjectDestroyed() ) ); + + delete m_pPart; + } + + setRun( 0L ); + //kdDebug(1202) << "KonqView::~KonqView " << this << " done" << endl; +} + +void KonqView::openURL( const KURL &url, const QString & locationBarURL, + const QString & nameFilter, bool tempFile ) +{ + kdDebug(1202) << "KonqView::openURL url=" << url << " locationBarURL=" << locationBarURL << endl; + setServiceTypeInExtension(); + + if (KonqMainWindow::s_crashlog_file) { + QString part_url; + if (m_pPart) + part_url = m_pPart->url().url(); + if (part_url.isNull()) + part_url = ""; + + QString url_url = url.url(); + if (url_url.isNull()) + url_url = QString(""); + + QCString line; + + line = ( QString("closed(%1):%2\n").arg(m_randID,0,16).arg(part_url) ).utf8(); + KonqMainWindow::s_crashlog_file->writeBlock(line,line.length()); + line = ( QString("opened(%3):%4\n").arg(m_randID,0,16).arg(url_url) ).utf8(); + KonqMainWindow::s_crashlog_file->writeBlock(line,line.length()); + KonqMainWindow::s_crashlog_file->flush(); + } + + KParts::BrowserExtension *ext = browserExtension(); + KParts::URLArgs args; + if ( ext ) + args = ext->urlArgs(); + + // Typing "Enter" again after the URL of an aborted view, triggers a reload. + if ( m_bAborted && m_pPart && m_pPart->url() == url && !args.doPost()) + { + if ( !prepareReload( args ) ) + return; + if ( ext ) + ext->setURLArgs( args ); + } + +#ifdef DEBUG_HISTORY + kdDebug(1202) << "m_bLockedLocation=" << m_bLockedLocation << " args.lockHistory()=" << args.lockHistory() << endl; +#endif + if ( args.lockHistory() ) + lockHistory(); + + if ( !m_bLockHistory ) + { + // Store this new URL in the history, removing any existing forward history. + // We do this first so that everything is ready if a part calls completed(). + createHistoryEntry(); + } else + m_bLockHistory = false; + + callExtensionStringMethod( "setNameFilter(const QString&)", nameFilter ); + if ( m_bDisableScrolling ) + callExtensionMethod( "disableScrolling()" ); + + setLocationBarURL( locationBarURL ); + setPageSecurity(KonqMainWindow::NotCrypted); + + if ( !args.reload ) + { + // Save the POST data that is necessary to open this URL + // (so that reload can re-post it) + m_doPost = args.doPost(); + m_postContentType = args.contentType(); + m_postData = args.postData; + // Save the referrer + m_pageReferrer = args.metaData()["referrer"]; + } + + if ( tempFile ) { + // Store the path to the tempfile. Yes, we could store a bool only, + // but this would be more dangerous. If anything goes wrong in the code, + // we might end up deleting a real file. + if ( url.isLocalFile() ) + m_tempFile = url.path(); + else + kdWarning(1202) << "Tempfile option is set, but URL is remote: " << url << endl; + } + + aboutToOpenURL( url, args ); + + m_pPart->openURL( url ); + + updateHistoryEntry(false /* don't save location bar URL yet */); + // add pending history entry + KonqHistoryManager::kself()->addPending( url, locationBarURL, QString::null); + +#ifdef DEBUG_HISTORY + kdDebug(1202) << "Current position : " << m_lstHistory.at() << endl; +#endif +} + +void KonqView::switchView( KonqViewFactory &viewFactory ) +{ + kdDebug(1202) << "KonqView::switchView" << endl; + if ( m_pPart ) + m_pPart->widget()->hide(); + + KParts::ReadOnlyPart *oldPart = m_pPart; + m_pPart = m_pKonqFrame->attach( viewFactory ); // creates the part + + // Set the statusbar in the BE asap to avoid a KMainWindow statusbar being created. + KParts::StatusBarExtension* sbext = statusBarExtension(); + if ( sbext ) + sbext->setStatusBar( frame()->statusbar() ); + + // Activate the new part + if ( oldPart ) + { + m_pPart->setName( oldPart->name() ); + emit sigPartChanged( this, oldPart, m_pPart ); + delete oldPart; + } + + connectPart(); + + QVariant prop; + + prop = m_service->property( "X-KDE-BrowserView-FollowActive"); + if (prop.isValid() && prop.toBool()) + { + //kdDebug(1202) << "KonqView::switchView X-KDE-BrowserView-FollowActive -> setFollowActive" <<endl; + setFollowActive(true); + } + + prop = m_service->property( "X-KDE-BrowserView-Built-Into" ); + m_bBuiltinView = (prop.isValid() && prop.toString() == "konqueror"); + + if ( !m_pMainWindow->viewManager()->isLoadingProfile() ) + { + // Honour "non-removeable passive mode" (like the dirtree) + prop = m_service->property( "X-KDE-BrowserView-PassiveMode"); + if ( prop.isValid() && prop.toBool() ) + { + kdDebug(1202) << "KonqView::switchView X-KDE-BrowserView-PassiveMode -> setPassiveMode" << endl; + setPassiveMode( true ); // set as passive + } + + // Honour "linked view" + prop = m_service->property( "X-KDE-BrowserView-LinkedView"); + if ( prop.isValid() && prop.toBool() ) + { + setLinkedView( true ); // set as linked + // Two views : link both + if (m_pMainWindow->viewCount() <= 2) // '1' can happen if this view is not yet in the map + { + KonqView * otherView = m_pMainWindow->otherView( this ); + if (otherView) + otherView->setLinkedView( true ); + } + } + } + + prop = m_service->property( "X-KDE-BrowserView-HierarchicalView"); + if ( prop.isValid() && prop.toBool() ) + { + kdDebug() << "KonqView::switchView X-KDE-BrowserView-HierarchicalView -> setHierarchicalView" << endl; + setHierarchicalView( true ); // set as hierarchial + } + else + { + setHierarchicalView( false ); + } +} + +bool KonqView::changeViewMode( const QString &serviceType, + const QString &serviceName, + bool forceAutoEmbed ) +{ + // Caller should call stop first. + assert ( !m_bLoading ); + + kdDebug(1202) << "changeViewMode: serviceType is " << serviceType + << " serviceName is " << serviceName + << " current service name is " << m_service->desktopEntryName() << endl; + + if ( KMimeType::mimeType(serviceType)->is(m_serviceType) && (serviceName.isEmpty() || serviceName == m_service->desktopEntryName()) ) + return true; + + if ( isLockedViewMode() ) + { + //kdDebug(1202) << "This view's mode is locked - can't change" << endl; + return false; // we can't do that if our view mode is locked + } + + kdDebug(1202) << "Switching view modes..." << endl; + KTrader::OfferList partServiceOffers, appServiceOffers; + KService::Ptr service = 0L; + KonqViewFactory viewFactory = KonqFactory::createView( serviceType, serviceName, &service, &partServiceOffers, &appServiceOffers, forceAutoEmbed ); + + if ( viewFactory.isNull() ) + { + // Revert location bar's URL to the working one + if(history().current()) + setLocationBarURL( history().current()->locationBarURL ); + return false; + } + + m_serviceType = serviceType; + m_partServiceOffers = partServiceOffers; + m_appServiceOffers = appServiceOffers; + + // Check if that's already the kind of part we have -> no need to recreate it + // Note: we should have an operator= for KService... + if ( m_service && m_service->desktopEntryPath() == service->desktopEntryPath() ) + { + kdDebug( 1202 ) << "KonqView::changeViewMode. Reusing service. Service type set to " << m_serviceType << endl; + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->updateViewModeActions(); + } + else + { + m_service = service; + + switchView( viewFactory ); + } + + if ( m_pMainWindow->viewManager()->activePart() != m_pPart ) + { + // Make the new part active. Note that we don't do it each time we + // open a URL (becomes awful in view-follows-view mode), but we do + // each time we change the view mode. + // We don't do it in switchView either because it's called from the constructor too, + // where the location bar url isn't set yet. + //kdDebug(1202) << "Giving focus to new part " << m_pPart << endl; + m_pMainWindow->viewManager()->setActivePart( m_pPart ); + } + return true; +} + +void KonqView::connectPart( ) +{ + //kdDebug(1202) << "KonqView::connectPart" << endl; + connect( m_pPart, SIGNAL( started( KIO::Job * ) ), + this, SLOT( slotStarted( KIO::Job * ) ) ); + connect( m_pPart, SIGNAL( completed() ), + this, SLOT( slotCompleted() ) ); + connect( m_pPart, SIGNAL( completed(bool) ), + this, SLOT( slotCompleted(bool) ) ); + connect( m_pPart, SIGNAL( canceled( const QString & ) ), + this, SLOT( slotCanceled( const QString & ) ) ); + connect( m_pPart, SIGNAL( setWindowCaption( const QString & ) ), + this, SLOT( setCaption( const QString & ) ) ); + + KParts::BrowserExtension *ext = browserExtension(); + + if ( ext ) + { + ext->setBrowserInterface( m_browserIface ); + + connect( ext, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs &) ), + m_pMainWindow, SLOT( slotOpenURLRequest( const KURL &, const KParts::URLArgs & ) ) ); + + if ( m_bPopupMenuEnabled ) + { + m_bPopupMenuEnabled = false; // force + enablePopupMenu( true ); + } + + connect( ext, SIGNAL( setLocationBarURL( const QString & ) ), + this, SLOT( setLocationBarURL( const QString & ) ) ); + + connect( ext, SIGNAL( setIconURL( const KURL & ) ), + this, SLOT( setIconURL( const KURL & ) ) ); + + connect( ext, SIGNAL( setPageSecurity( int ) ), + this, SLOT( setPageSecurity( int ) ) ); + + connect( ext, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ), + m_pMainWindow, SLOT( slotCreateNewWindow( const KURL &, const KParts::URLArgs & ) ) ); + + connect( ext, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ), + m_pMainWindow, SLOT( slotCreateNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ) ); + + connect( ext, SIGNAL( loadingProgress( int ) ), + m_pKonqFrame->statusbar(), SLOT( slotLoadingProgress( int ) ) ); + + connect( ext, SIGNAL( speedProgress( int ) ), + m_pKonqFrame->statusbar(), SLOT( slotSpeedProgress( int ) ) ); + + connect( ext, SIGNAL( selectionInfo( const KFileItemList & ) ), + this, SLOT( slotSelectionInfo( const KFileItemList & ) ) ); + + connect( ext, SIGNAL( mouseOverInfo( const KFileItem * ) ), + this, SLOT( slotMouseOverInfo( const KFileItem * ) ) ); + + connect( ext, SIGNAL( openURLNotify() ), + this, SLOT( slotOpenURLNotify() ) ); + + connect( ext, SIGNAL( enableAction( const char *, bool ) ), + this, SLOT( slotEnableAction( const char *, bool ) ) ); + + connect( ext, SIGNAL( setActionText( const char *, const QString& ) ), + this, SLOT( slotSetActionText( const char *, const QString& ) ) ); + + connect( ext, SIGNAL( moveTopLevelWidget( int, int ) ), + this, SLOT( slotMoveTopLevelWidget( int, int ) ) ); + + connect( ext, SIGNAL( resizeTopLevelWidget( int, int ) ), + this, SLOT( slotResizeTopLevelWidget( int, int ) ) ); + + connect( ext, SIGNAL( requestFocus(KParts::ReadOnlyPart *) ), + this, SLOT( slotRequestFocus(KParts::ReadOnlyPart *) ) ); + + if (service()->desktopEntryName() != "konq_sidebartng") { + connect( ext, SIGNAL( infoMessage( const QString & ) ), + m_pKonqFrame->statusbar(), SLOT( message( const QString & ) ) ); + + connect( ext, + SIGNAL( addWebSideBar(const KURL&, const QString&) ), + m_pMainWindow, + SLOT( slotAddWebSideBar(const KURL&, const QString&) ) ); + } + + callExtensionBoolMethod( "setSaveViewPropertiesLocally(bool)", m_pMainWindow->saveViewPropertiesLocally() ); + } + + QVariant urlDropHandling; + + if ( ext ) + urlDropHandling = ext->property( "urlDropHandling" ); + else + urlDropHandling = QVariant( true, 0 ); + + // Handle url drops if + // a) either the property says "ok" + // or + // b) the part is a plain krop (no BE) + m_bURLDropHandling = ( urlDropHandling.type() == QVariant::Bool && + urlDropHandling.toBool() ); + + m_pPart->widget()->installEventFilter( this ); + + if (m_bBackRightClick && m_pPart->widget()->inherits("QScrollView") ) + { + (static_cast<QScrollView *>(m_pPart->widget()))->viewport()->installEventFilter( this ); + } + + // KonqDirPart signal + if ( m_pPart->inherits("KonqDirPart") ) + { + connect( m_pPart, SIGNAL( findOpen( KonqDirPart * ) ), + m_pMainWindow, SLOT( slotFindOpen( KonqDirPart * ) ) ); + } +} + +void KonqView::slotEnableAction( const char * name, bool enabled ) +{ + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->enableAction( name, enabled ); + // Otherwise, we don't have to do anything, the state of the action is + // stored inside the browser-extension. +} + +void KonqView::slotSetActionText( const char* name, const QString& text ) +{ + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->setActionText( name, text ); + // Otherwise, we don't have to do anything, the state of the action is + // stored inside the browser-extension. +} + +void KonqView::slotMoveTopLevelWidget( int x, int y ) +{ + KonqFrameContainerBase* container = frame()->parentContainer(); + // If tabs are shown, only accept to move the whole window if there's only one tab. + if ( container->frameType() != "Tabs" || static_cast<KonqFrameTabs*>(container)->count() == 1 ) + m_pMainWindow->move( x, y ); +} + +void KonqView::slotResizeTopLevelWidget( int w, int h ) +{ + KonqFrameContainerBase* container = frame()->parentContainer(); + // If tabs are shown, only accept to resize the whole window if there's only one tab. + // ### Maybe we could store the size requested by each tab and resize the window to the biggest one. + if ( container->frameType() != "Tabs" || static_cast<KonqFrameTabs*>(container)->count() == 1 ) + m_pMainWindow->resize( w, h ); +} + +void KonqView::slotStarted( KIO::Job * job ) +{ + //kdDebug(1202) << "KonqView::slotStarted" << job << endl; + setLoading( true ); + + if (job) + { + // Manage passwords properly... + if (m_pMainWindow) + { + kdDebug(7035) << "slotStarted: Window ID = " << m_pMainWindow->topLevelWidget()->winId() << endl; + job->setWindow (m_pMainWindow->topLevelWidget ()); + } + + connect( job, SIGNAL( percent( KIO::Job *, unsigned long ) ), this, SLOT( slotPercent( KIO::Job *, unsigned long ) ) ); + connect( job, SIGNAL( speed( KIO::Job *, unsigned long ) ), this, SLOT( slotSpeed( KIO::Job *, unsigned long ) ) ); + connect( job, SIGNAL( infoMessage( KIO::Job *, const QString & ) ), this, SLOT( slotInfoMessage( KIO::Job *, const QString & ) ) ); + } +} + +void KonqView::slotRequestFocus( KParts::ReadOnlyPart * ) +{ + m_pMainWindow->viewManager()->showTab(this); +} + +void KonqView::setLoading( bool loading, bool hasPending /*= false*/) +{ + //kdDebug(1202) << "KonqView::setLoading loading=" << loading << " hasPending=" << hasPending << endl; + m_bLoading = loading; + m_bPendingRedirection = hasPending; + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->updateToolBarActions( hasPending ); + + m_pMainWindow->viewManager()->setLoading( this, loading || hasPending ); +} + +void KonqView::slotPercent( KIO::Job *, unsigned long percent ) +{ + m_pKonqFrame->statusbar()->slotLoadingProgress( percent ); +} + +void KonqView::slotSpeed( KIO::Job *, unsigned long bytesPerSecond ) +{ + m_pKonqFrame->statusbar()->slotSpeedProgress( bytesPerSecond ); +} + +void KonqView::slotInfoMessage( KIO::Job *, const QString &msg ) +{ + m_pKonqFrame->statusbar()->message( msg ); +} + +void KonqView::slotCompleted() +{ + slotCompleted( false ); +} + +void KonqView::slotCompleted( bool hasPending ) +{ + //kdDebug(1202) << "KonqView::slotCompleted hasPending=" << hasPending << endl; + m_pKonqFrame->statusbar()->slotLoadingProgress( -1 ); + + if ( ! m_bLockHistory ) + { + // Success... update history entry, including location bar URL + updateHistoryEntry( true ); + + if ( m_bAborted ) // remove the pending entry on error + KonqHistoryManager::kself()->removePending( url() ); + else if ( m_lstHistory.current() ) // register as proper history entry + KonqHistoryManager::kself()->confirmPending(url(), typedURL(), + m_lstHistory.current()->title); + + emit viewCompleted( this ); + } + setLoading( false, hasPending ); + + if (!m_bGotIconURL && !m_bAborted) + { + if ( KonqSettings::enableFavicon() == true ) + { + // Try to get /favicon.ico + if ( supportsServiceType( "text/html" ) && url().protocol().startsWith( "http" ) ) + KonqPixmapProvider::downloadHostIcon( url() ); + } + } +} + +void KonqView::slotCanceled( const QString & errorMsg ) +{ + kdDebug(1202) << "KonqView::slotCanceled" << endl; + // The errorMsg comes from the ReadOnlyPart's job. + // It should probably be used in a KMessageBox + // Let's use the statusbar for now + m_pKonqFrame->statusbar()->message( errorMsg ); + m_bAborted = true; + slotCompleted(); +} + +void KonqView::slotSelectionInfo( const KFileItemList &items ) +{ + KonqFileSelectionEvent ev( items, m_pPart ); + QApplication::sendEvent( m_pMainWindow, &ev ); +} + +void KonqView::slotMouseOverInfo( const KFileItem *item ) +{ + KonqFileMouseOverEvent ev( item, m_pPart ); + QApplication::sendEvent( m_pMainWindow, &ev ); +} + +void KonqView::setLocationBarURL( const KURL& locationBarURL ) +{ + setLocationBarURL( locationBarURL.pathOrURL() ); +} + +void KonqView::setLocationBarURL( const QString & locationBarURL ) +{ + //kdDebug(1202) << "KonqView::setLocationBarURL " << locationBarURL << " this=" << this << endl; + + m_sLocationBarURL = locationBarURL; + if ( m_pMainWindow->currentView() == this ) + { + //kdDebug(1202) << "is current view " << this << endl; + m_pMainWindow->setLocationBarURL( m_sLocationBarURL ); + m_pMainWindow->setPageSecurity( m_pageSecurity ); + } + if (!m_bPassiveMode) setTabIcon( KURL::fromPathOrURL( m_sLocationBarURL ) ); +} + +void KonqView::setIconURL( const KURL & iconURL ) +// This function sets the favIcon in konqui's window if enabled, +// thus it is responsible for the icon in the taskbar. +// It does not set the tab's favIcon. +{ + kdDebug(1202) << "entering KonqView::setIconURL" << endl; + if ( KonqSettings::enableFavicon() ) + { + KonqPixmapProvider::setIconForURL( KURL( m_sLocationBarURL ), iconURL ); + m_bGotIconURL = true; + } +} + +void KonqView::setPageSecurity( int pageSecurity ) +{ + m_pageSecurity = (KonqMainWindow::PageSecurity)pageSecurity; + + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->setPageSecurity( m_pageSecurity ); +} + +void KonqView::setTabIcon( const KURL &url ) +{ + if (!m_bPassiveMode) frame()->setTabIcon( url, 0L ); +} + +void KonqView::setCaption( const QString & caption ) +{ + if (caption.isEmpty()) return; + + QString adjustedCaption = caption; + // For local URLs we prefer to use only the directory name + if (url().isLocalFile()) + { + // Is the caption a URL? If so, is it local? If so, only display the filename! + KURL url = KURL::fromPathOrURL(caption); + if (url.isValid() && url.isLocalFile() && url.fileName() == this->url().fileName()) + adjustedCaption = url.fileName(); + } + + m_caption = adjustedCaption; + if (!m_bPassiveMode) frame()->setTitle( adjustedCaption , 0L ); +} + +void KonqView::slotOpenURLNotify() +{ +#ifdef DEBUG_HISTORY + kdDebug(1202) << "KonqView::slotOpenURLNotify" << endl; +#endif + updateHistoryEntry(true); + createHistoryEntry(); + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->updateToolBarActions(); +} + +void KonqView::createHistoryEntry() +{ + // First, remove any forward history + HistoryEntry * current = m_lstHistory.current(); + if (current) + { +#ifdef DEBUG_HISTORY + kdDebug(1202) << "Truncating history" << endl; +#endif + m_lstHistory.at( m_lstHistory.count() - 1 ); // go to last one + for ( ; m_lstHistory.current() != current ; ) + { + if ( !m_lstHistory.removeLast() ) // and remove from the end (faster and easier) + assert(0); + // go to last one. The documentation says that removeLast() + // makes current() null if it's the last item. however in qt2 + // the behaviour was different than the documentation. this is + // changed in qt3 to behave as documented ;-) (Simon) + m_lstHistory.at( m_lstHistory.count() - 1 ); + } + // Now current is the current again. + } + // Append a new entry +#ifdef DEBUG_HISTORY + kdDebug(1202) << "Append a new entry" << endl; +#endif + m_lstHistory.append( new HistoryEntry ); // made current +#ifdef DEBUG_HISTORY + kdDebug(1202) << "at=" << m_lstHistory.at() << " count=" << m_lstHistory.count() << endl; +#endif + assert( m_lstHistory.at() == (int) m_lstHistory.count() - 1 ); +} + +void KonqView::updateHistoryEntry( bool saveLocationBarURL ) +{ + Q_ASSERT( !m_bLockHistory ); // should never happen + + HistoryEntry * current = m_lstHistory.current(); + if ( !current ) + return; + + if ( browserExtension() ) + { + current->buffer = QByteArray(); // Start with empty buffer. + QDataStream stream( current->buffer, IO_WriteOnly ); + + browserExtension()->saveState( stream ); + } + +#ifdef DEBUG_HISTORY + kdDebug(1202) << "Saving part URL : " << m_pPart->url() << " in history position " << m_lstHistory.at() << endl; +#endif + current->url = m_pPart->url(); + + if (saveLocationBarURL) + { +#ifdef DEBUG_HISTORY + kdDebug(1202) << "Saving location bar URL : " << m_sLocationBarURL << " in history position " << m_lstHistory.at() << endl; +#endif + current->locationBarURL = m_sLocationBarURL; + current->pageSecurity = m_pageSecurity; + } +#ifdef DEBUG_HISTORY + kdDebug(1202) << "Saving title : " << m_caption << " in history position " << m_lstHistory.at() << endl; +#endif + current->title = m_caption; + current->strServiceType = m_serviceType; + current->strServiceName = m_service->desktopEntryName(); + + current->doPost = m_doPost; + current->postData = m_doPost ? m_postData : QByteArray(); + current->postContentType = m_doPost ? m_postContentType : QString::null; + current->pageReferrer = m_pageReferrer; +} + +void KonqView::goHistory( int steps ) +{ + // This is called by KonqBrowserInterface + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->viewManager()->setActivePart( part() ); + + // Delay the go() call (we need to return to the caller first) + m_pMainWindow->slotGoHistoryActivated( steps ); +} + +void KonqView::go( int steps ) +{ + if ( !steps ) // [WildFox] i bet there are sites on the net with stupid devs who do that :) + { +#ifdef DEBUG_HISTORY + kdDebug(1202) << "KonqView::go(0)" << endl; +#endif + // [David] and you're right. And they expect that it reloads, apparently. + // [George] I'm going to make nspluginviewer rely on this too. :-) + m_pMainWindow->slotReload(); + return; + } + + int newPos = m_lstHistory.at() + steps; +#ifdef DEBUG_HISTORY + kdDebug(1202) << "go : steps=" << steps + << " newPos=" << newPos + << " m_lstHistory.count()=" << m_lstHistory.count() + << endl; +#endif + if( newPos < 0 || (uint)newPos >= m_lstHistory.count() ) + return; + + stop(); + + // Yay, we can move there without a loop ! + HistoryEntry *currentHistoryEntry = m_lstHistory.at( newPos ); // sets current item + + assert( currentHistoryEntry ); + assert( newPos == m_lstHistory.at() ); // check we moved (i.e. if I understood the docu) + assert( currentHistoryEntry == m_lstHistory.current() ); +#ifdef DEBUG_HISTORY + kdDebug(1202) << "New position " << m_lstHistory.at() << endl; +#endif + + restoreHistory(); +} + +void KonqView::restoreHistory() +{ + HistoryEntry h( *(m_lstHistory.current()) ); // make a copy of the current history entry, as the data + // the pointer points to will change with the following calls + +#ifdef DEBUG_HISTORY + kdDebug(1202) << "Restoring servicetype/name, and location bar URL from history : " << h.locationBarURL << endl; +#endif + setLocationBarURL( h.locationBarURL ); + setPageSecurity( h.pageSecurity ); + m_sTypedURL = QString::null; + if ( ! changeViewMode( h.strServiceType, h.strServiceName ) ) + { + kdWarning(1202) << "Couldn't change view mode to " << h.strServiceType + << " " << h.strServiceName << endl; + return /*false*/; + } + + setServiceTypeInExtension(); + + aboutToOpenURL( h.url ); + + if ( browserExtension() ) + { + //kdDebug(1202) << "Restoring view from stream" << endl; + QDataStream stream( h.buffer, IO_ReadOnly ); + + browserExtension()->restoreState( stream ); + + m_doPost = h.doPost; + m_postContentType = h.postContentType; + m_postData = h.postData; + m_pageReferrer = h.pageReferrer; + } + else + m_pPart->openURL( h.url ); + + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->updateToolBarActions(); + +#ifdef DEBUG_HISTORY + kdDebug(1202) << "New position (2) " << m_lstHistory.at() << endl; +#endif +} + +const HistoryEntry * KonqView::historyAt(const int pos) +{ + if(pos<0 || pos>=(int)m_lstHistory.count()) + return 0L; + int oldpos = m_lstHistory.at(); + const HistoryEntry* h = m_lstHistory.at(pos); + m_lstHistory.at( oldpos ); + return h; +} + +void KonqView::copyHistory( KonqView *other ) +{ + m_lstHistory.clear(); + + QPtrListIterator<HistoryEntry> it( other->m_lstHistory ); + for (; it.current(); ++it ) + m_lstHistory.append( new HistoryEntry( *it.current() ) ); + m_lstHistory.at(other->m_lstHistory.at()); +} + +KURL KonqView::url() const +{ + assert( m_pPart ); + return m_pPart->url(); +} + +KURL KonqView::upURL() const +{ + KURL currentURL; + if ( m_pRun ) + currentURL = m_pRun->url(); + else + currentURL = KURL::fromPathOrURL( m_sLocationBarURL ); + return currentURL.upURL(); +} + +void KonqView::setRun( KonqRun * run ) +{ + if ( m_pRun ) + { + // Tell the KonqRun to abort, but don't delete it ourselves. + // It could be showing a message box right now. It will delete itself anyway. + m_pRun->abort(); + // finish() will be emitted later (when back to event loop) + // and we don't want it to call slotRunFinished (which stops the animation and stop button). + m_pRun->disconnect( m_pMainWindow ); + if ( !run ) + frame()->unsetCursor(); + } + else if ( run ) + frame()->setCursor( KCursor::workingCursor() ); + m_pRun = run; +} + +void KonqView::stop() +{ + //kdDebug(1202) << "KonqView::stop()" << endl; + m_bAborted = false; + finishedWithCurrentURL(); + if ( m_bLoading || m_bPendingRedirection ) + { + // aborted -> confirm the pending url. We might as well remove it, but + // we decided to keep it :) + KonqHistoryManager::kself()->confirmPending( url(), m_sTypedURL ); + + //kdDebug(1202) << "m_pPart->closeURL()" << endl; + m_pPart->closeURL(); + m_bAborted = true; + m_pKonqFrame->statusbar()->slotLoadingProgress( -1 ); + setLoading( false, false ); + } + if ( m_pRun ) + { + // Revert to working URL - unless the URL was typed manually + // This is duplicated with KonqMainWindow::slotRunFinished, but we can't call it + // since it relies on sender()... + if ( history().current() && m_pRun->typedURL().isEmpty() ) { // not typed + setLocationBarURL( history().current()->locationBarURL ); + setPageSecurity( history().current()->pageSecurity ); + } + + setRun( 0L ); + m_pKonqFrame->statusbar()->slotLoadingProgress( -1 ); + } + if ( !m_bLockHistory && m_lstHistory.count() > 0 ) + updateHistoryEntry(true); +} + +void KonqView::finishedWithCurrentURL() +{ + if ( !m_tempFile.isEmpty() ) + { + kdDebug(1202) << "######### Deleting tempfile after use:" << m_tempFile << endl; + QFile::remove( m_tempFile ); + m_tempFile = QString::null; + } +} + +void KonqView::setPassiveMode( bool mode ) +{ + // In theory, if m_bPassiveMode is true and mode is false, + // the part should be removed from the part manager, + // and if the other way round, it should be readded to the part manager... + m_bPassiveMode = mode; + + if ( mode && m_pMainWindow->viewCount() > 1 && m_pMainWindow->currentView() == this ) + { + KParts::Part * part = m_pMainWindow->viewManager()->chooseNextView( this )->part(); // switch active part + m_pMainWindow->viewManager()->setActivePart( part ); + } + + // Update statusbar stuff + m_pMainWindow->viewManager()->viewCountChanged(); +} + +void KonqView::setHierarchicalView( bool mode ) +{ + m_bHierarchicalView=mode; +} + + + +void KonqView::setLinkedView( bool mode ) +{ + m_bLinkedView = mode; + if ( m_pMainWindow->currentView() == this ) + m_pMainWindow->linkViewAction()->setChecked( mode ); + frame()->statusbar()->setLinkedView( mode ); +} + +void KonqView::setLockedLocation( bool b ) +{ + m_bLockedLocation = b; +} + +void KonqView::aboutToOpenURL( const KURL &url, const KParts::URLArgs &args ) +{ + KParts::OpenURLEvent ev( m_pPart, url, args ); + QApplication::sendEvent( m_pMainWindow, &ev ); + + m_bGotIconURL = false; + m_bAborted = false; +} + +void KonqView::setServiceTypeInExtension() +{ + KParts::BrowserExtension *ext = browserExtension(); + if ( !ext ) + return; + + KParts::URLArgs args( ext->urlArgs() ); + args.serviceType = m_serviceType; + ext->setURLArgs( args ); +} + +QStringList KonqView::frameNames() const +{ + return childFrameNames( m_pPart ); +} + +QStringList KonqView::childFrameNames( KParts::ReadOnlyPart *part ) +{ + QStringList res; + + KParts::BrowserHostExtension *hostExtension = KParts::BrowserHostExtension::childObject( part ); + + if ( !hostExtension ) + return res; + + res += hostExtension->frameNames(); + + const QPtrList<KParts::ReadOnlyPart> children = hostExtension->frames(); + QPtrListIterator<KParts::ReadOnlyPart> it( children ); + for (; it.current(); ++it ) + res += childFrameNames( it.current() ); + + return res; +} + +KParts::BrowserHostExtension* KonqView::hostExtension( KParts::ReadOnlyPart *part, const QString &name ) +{ + KParts::BrowserHostExtension *ext = KParts::BrowserHostExtension::childObject( part ); + + if ( !ext ) + return 0; + + if ( ext->frameNames().contains( name ) ) + return ext; + + const QPtrList<KParts::ReadOnlyPart> children = ext->frames(); + QPtrListIterator<KParts::ReadOnlyPart> it( children ); + for (; it.current(); ++it ) + { + KParts::BrowserHostExtension *childHost = hostExtension( it.current(), name ); + if ( childHost ) + return childHost; + } + + return 0; +} + +bool KonqView::callExtensionMethod( const char *methodName ) +{ + QObject *obj = KParts::BrowserExtension::childObject( m_pPart ); + if ( !obj ) // not all views have a browser extension ! + return false; + + int id = obj->metaObject()->findSlot( methodName ); + if ( id == -1 ) + return false; + QUObject o[ 1 ]; + + obj->qt_invoke( id, o ); + return true; +} + +bool KonqView::callExtensionBoolMethod( const char *methodName, bool value ) +{ + QObject *obj = KParts::BrowserExtension::childObject( m_pPart ); + if ( !obj ) // not all views have a browser extension ! + return false; + + int id = obj->metaObject()->findSlot( methodName ); + if ( id == -1 ) + return false; + QUObject o[ 2 ]; + + static_QUType_bool.set( o + 1, value ); + + obj->qt_invoke( id, o ); + return true; +} + +bool KonqView::callExtensionStringMethod( const char *methodName, QString value ) +{ + QObject *obj = KParts::BrowserExtension::childObject( m_pPart ); + if ( !obj ) // not all views have a browser extension ! + return false; + + int id = obj->metaObject()->findSlot( methodName ); + if ( id == -1 ) + return false; + QUObject o[ 2 ]; + + static_QUType_QString.set( o + 1, value ); + + obj->qt_invoke( id, o ); + return true; +} + +bool KonqView::callExtensionURLMethod( const char *methodName, const KURL& value ) +{ + QObject *obj = KParts::BrowserExtension::childObject( m_pPart ); + if ( !obj ) // not all views have a browser extension ! + return false; + + int id = obj->metaObject()->findSlot( methodName ); + if ( id == -1 ) + return false; + QUObject o[ 2 ]; + + static_QUType_ptr.set( o + 1, &value ); + + obj->qt_invoke( id, o ); + return true; +} + +void KonqView::setViewName( const QString &name ) +{ + //kdDebug() << "KonqView::setViewName this=" << this << " name=" << name << endl; + if ( m_pPart ) + m_pPart->setName( name.local8Bit().data() ); +} + +QString KonqView::viewName() const +{ + return m_pPart ? QString::fromLocal8Bit( m_pPart->name() ) : QString::null; +} + +void KonqView::enablePopupMenu( bool b ) +{ + Q_ASSERT( m_pMainWindow ); + + KParts::BrowserExtension *ext = browserExtension(); + + if ( !ext ) + return; + + if ( m_bPopupMenuEnabled == b ) + return; + + // enable context popup + if ( b ) { + m_bPopupMenuEnabled = true; + + connect( ext, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ), + m_pMainWindow, SLOT( slotPopupMenu( const QPoint &, const KFileItemList & ) ) ); + + connect( ext, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ), + m_pMainWindow, SLOT( slotPopupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) ); + + connect( ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ), + m_pMainWindow, SLOT( slotPopupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) ); + + connect( ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ), + m_pMainWindow, SLOT( slotPopupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ) ); + + connect( ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ), + m_pMainWindow, SLOT( slotPopupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) ); + + connect( ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ), + m_pMainWindow, SLOT( slotPopupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ) ); + } + else // disable context popup + { + m_bPopupMenuEnabled = false; + + disconnect( ext, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ), + m_pMainWindow, SLOT( slotPopupMenu( const QPoint &, const KFileItemList & ) ) ); + + disconnect( ext, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ), + m_pMainWindow, SLOT( slotPopupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) ); + + disconnect( ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ), + m_pMainWindow, SLOT( slotPopupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) ); + + disconnect( ext, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ), + m_pMainWindow, SLOT( slotPopupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) ); + } + enableBackRightClick( m_bBackRightClick ); +} + +// caller should ensure that this is called only when b changed, or for new parts +void KonqView::enableBackRightClick( bool b ) +{ + m_bBackRightClick = b; + if ( b ) + connect( this, SIGNAL( backRightClick() ), + m_pMainWindow, SLOT( slotBack() ) ); + else + disconnect( this, SIGNAL( backRightClick() ), + m_pMainWindow, SLOT( slotBack() ) ); +} + +void KonqView::reparseConfiguration() +{ + callExtensionMethod( "reparseConfiguration()" ); + bool b = KonqSettings::backRightClick(); + if ( m_bBackRightClick != b ) + { + if (m_bBackRightClick && m_pPart->widget()->inherits("QScrollView") ) + { + (static_cast<QScrollView *>(m_pPart->widget()))->viewport()->installEventFilter( this ); + } + enableBackRightClick( b ); + } +} + +void KonqView::disableScrolling() +{ + m_bDisableScrolling = true; + callExtensionMethod( "disableScrolling()" ); +} + +KonqViewIface * KonqView::dcopObject() +{ + if ( !m_dcopObject ) { + QCString dcopName = name(); + if ( dcopName.isEmpty() || dcopName == "unnamed" ) + dcopName = viewName().utf8(); + if ( dcopName.isEmpty() || dcopName == "unnamed" ) { + QVariant dcopProperty = part()->property( "dcopObjectId" ); + if ( dcopProperty.type() == QVariant::CString ) + dcopName = dcopProperty.toCString(); + } + dcopName += "-view"; // to avoid having the same name as the part + m_dcopObject = new KonqViewIface( this, dcopName ); + } + return m_dcopObject; +} + +bool KonqView::eventFilter( QObject *obj, QEvent *e ) +{ + if ( !m_pPart ) + return false; +// kdDebug() << "--" << obj->className() << "--" << e->type() << "--" << endl; + if ( e->type() == QEvent::DragEnter && m_bURLDropHandling && obj == m_pPart->widget() ) + { + QDragEnterEvent *ev = static_cast<QDragEnterEvent *>( e ); + + if ( KURLDrag::canDecode( ev ) ) + { + KURL::List lstDragURLs; + bool ok = KURLDrag::decode( ev, lstDragURLs ); + + QObjectList *children = m_pPart->widget()->queryList( "QWidget" ); + + if ( ok && + !lstDragURLs.first().url().contains( "javascript:", false ) && // ### this looks like a hack to me + ev->source() != m_pPart->widget() && + children && + children->findRef( ev->source() ) == -1 ) + ev->acceptAction(); + + delete children; + } + } + else if ( e->type() == QEvent::Drop && m_bURLDropHandling && obj == m_pPart->widget() ) + { + QDropEvent *ev = static_cast<QDropEvent *>( e ); + + KURL::List lstDragURLs; + bool ok = KURLDrag::decode( ev, lstDragURLs ); + + KParts::BrowserExtension *ext = browserExtension(); + if ( ok && ext && lstDragURLs.first().isValid() ) + emit ext->openURLRequest( lstDragURLs.first() ); // this will call m_pMainWindow::slotOpenURLRequest delayed + } + + if ( m_bBackRightClick ) + { + if ( e->type() == QEvent::ContextMenu ) + { + QContextMenuEvent *ev = static_cast<QContextMenuEvent *>( e ); + if ( ev->reason() == QContextMenuEvent::Mouse ) + { + return true; + } + } + else if ( e->type() == QEvent::MouseButtonPress ) + { + QMouseEvent *ev = static_cast<QMouseEvent *>( e ); + if ( ev->button() == RightButton ) + { + return true; + } + } + else if ( e->type() == QEvent::MouseButtonRelease ) + { + QMouseEvent *ev = static_cast<QMouseEvent *>( e ); + if ( ev->button() == RightButton ) + { + emit backRightClick(); + return true; + } + } + else if ( e->type() == QEvent::MouseMove ) + { + QMouseEvent *ev = static_cast<QMouseEvent *>( e ); + if ( ev->state() == RightButton ) + { + obj->removeEventFilter( this ); + QMouseEvent me( QEvent::MouseButtonPress, ev->pos(), 2, 2 ); + QApplication::sendEvent( obj, &me ); + QContextMenuEvent ce( QContextMenuEvent::Mouse, ev->pos(), 2 ); + QApplication::sendEvent( obj, &ce ); + obj->installEventFilter( this ); + return true; + } + } + } + + if ( e->type() == QEvent::FocusIn ) + { + setActiveInstance(); + } + return false; +} + +void KonqView::setActiveInstance() +{ + if ( m_bBuiltinView || !m_pPart->instance() /*never!*/) + KGlobal::_activeInstance = KGlobal::instance(); + else + KGlobal::_activeInstance = m_pPart->instance(); +} + +bool KonqView::prepareReload( KParts::URLArgs& args ) +{ + args.reload = true; + // Repost form data if this URL is the result of a POST HTML form. + if ( m_doPost && !args.redirectedRequest() ) + { + if ( KMessageBox::warningContinueCancel( 0, i18n( + "The page you are trying to view is the result of posted form data. " + "If you resend the data, any action the form carried out (such as search or online purchase) will be repeated. "), + i18n( "Warning" ), i18n( "Resend" ) ) == KMessageBox::Continue ) + { + args.setDoPost( true ); + args.setContentType( m_postContentType ); + args.postData = m_postData; + } + else + return false; + } + // Re-set referrer + args.metaData()["referrer"] = m_pageReferrer; + + return true; +} + +KParts::BrowserExtension * KonqView::browserExtension() const +{ + return KParts::BrowserExtension::childObject( m_pPart ); +} + +KParts::StatusBarExtension * KonqView::statusBarExtension() const +{ + return KParts::StatusBarExtension::childObject( m_pPart ); +} + +bool KonqView::supportsServiceType( const QString &serviceType ) const +{ + const QStringList lst = serviceTypes(); + for( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + if ( *it == serviceType ) + return true; + // Maybe we should keep around a list of KServiceType::Ptr? + KMimeType::Ptr mime = KMimeType::mimeType( *it ); + if ( mime && mime->is( serviceType ) ) // respect inheritance + return true; + } + return false; +} + +#include "konq_view.moc" diff --git a/konqueror/konq_view.h b/konqueror/konq_view.h new file mode 100644 index 000000000..24bec3110 --- /dev/null +++ b/konqueror/konq_view.h @@ -0,0 +1,479 @@ +/* -*- c-basic-offset: 2 -*- + * This file is part of the KDE project + * Copyright (C) 1998-2005 David Faure <[email protected]> + * + * 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_view_h__ +#define __konq_view_h__ + +#include "konq_mainwindow.h" +#include "konq_factory.h" + +#include <qptrlist.h> +#include <qstring.h> +#include <qobject.h> +#include <qstringlist.h> +#include <qguardedptr.h> +#include <qcstring.h> + +#include <ktrader.h> + +class KonqRun; +class KonqFrame; +class KonqViewIface; +class KonqBrowserInterface; +namespace KParts +{ + class BrowserExtension; + class StatusBarExtension; +} + +struct HistoryEntry +{ + KURL url; + QString locationBarURL; // can be different from url when showing a index.html + QString title; + QByteArray buffer; + QString strServiceType; + QString strServiceName; + QByteArray postData; + QString postContentType; + bool doPost; + QString pageReferrer; + KonqMainWindow::PageSecurity pageSecurity; +}; + +/* This class represents a child of the main view. The main view maintains + * the list of children. A KonqView contains a Browser::View and + * handles it. It's more or less the backend structure for the views. + * The widget handling stuff is done by the KonqFrame. + */ +class KonqView : public QObject +{ + Q_OBJECT +public: + + /** + * Create a konqueror view + * @param viewFactory the factory to be used to create the part + * @param viewFrame the frame where to create the view + * @param mainWindow is the main window :-) + * @param service the service implementing the part + * @param partServiceOffers list of part offers found by the factory + * @param appServiceOffers list of app offers found by the factory + * @param serviceType the serviceType implemented by the part + * @param passiveMode whether to initially make the view passive + */ + KonqView( KonqViewFactory &viewFactory, + KonqFrame* viewFrame, + KonqMainWindow * mainWindow, + const KService::Ptr &service, + const KTrader::OfferList &partServiceOffers, + const KTrader::OfferList &appServiceOffers, + const QString &serviceType, + bool passiveMode); + + ~KonqView(); + + /** + * Displays another URL, but without changing the view mode (caller has to + * ensure that the call makes sense) + * @param url the URL to open + * @param locationBarURL the URL to set in the location bar (see @ref setLocationBarURL) + * @param nameFilter e.g. *.cpp + * @param tempFile whether to delete the file after use + */ + void openURL( const KURL &url, + const QString & locationBarURL, + const QString &nameFilter = QString::null, + bool tempFile = false ); + + /** + * Change the type of view (i.e. loads a new konqueror view) + * Contract: the caller should call stop() first, + * + * @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 = QString::null, + bool forceAutoEmbed = false ); + + /** + * Call this to prevent next openURL() call from changing history lists + * Used when the same URL is reloaded (for instance with another view mode) + * + * Calling with lock=false is a hack reserved to the "find" feature. + */ + void lockHistory( bool lock = true ) { m_bLockHistory = lock; } + + /** + * @return true if view can go back + */ + bool canGoBack()const { return m_lstHistory.at() > 0; } + + /** + * @return true if view can go forward + */ + bool canGoForward()const { return m_lstHistory.at() != ((int)m_lstHistory.count())-1; } + + /** + * @return the position in the history + */ + int historyPos() const { return m_lstHistory.at(); } + + uint historyLength() { return m_lstHistory.count(); } + + /** + * Move in history. +1 is "forward", -1 is "back", you can guess the rest. + */ + void go( int steps ); + + /** + * Helper function for go() and KonqViewManager + */ + void restoreHistory(); + + void setHistoryPos(int newPos) { m_lstHistory.at( newPos ); } + + /** + * @return the history of this view + */ + const QPtrList<HistoryEntry> & history() { return m_lstHistory; } + + /** + * @return the HistoryEntry at postion @p pos + */ + const HistoryEntry* historyAt(const int pos); + + /** + * Creates a deep copy of the @p other view's history buffers. + */ + void copyHistory( KonqView *other ); + + /** + * Set the KonqRun instance that is running something for this view + * The main window uses this to store the KonqRun for each child view. + */ + void setRun( KonqRun * run ); + + KonqRun *run() const { return m_pRun; } + + /** + * Stop loading + */ + void stop(); + + /** + * Retrieve view's URL + */ + KURL url() const; + + KURL upURL() const; + + /** + * 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() const { return m_sLocationBarURL; } + + /** + * Get the URL that was typed to get the current URL. + */ + QString typedURL() const { return m_sTypedURL; } + /** + * Set the URL that was typed to get the current URL. + */ + void setTypedURL( const QString & u ) { m_sTypedURL = u; } + + /** + * Return the security state of page in view + */ + KonqMainWindow::PageSecurity pageSecurity() const { return m_pageSecurity; } + + /** + * @return the part embedded into this view + */ + KParts::ReadOnlyPart *part() const { return m_pPart; } + + /** + * see KonqViewManager::removePart + */ + void partDeleted() { m_pPart = 0L; } + + KParts::BrowserExtension *browserExtension() const; + + KParts::StatusBarExtension *statusBarExtension() const; + + /** + * @return a pointer to the KonqFrame which the view lives in + */ + KonqFrame* frame() const { return m_pKonqFrame; } + + /** + * @return the servicetype this view is currently displaying + */ + QString serviceType() const { return m_serviceType; } + + /** + * @return the servicetypes this view is capable to display + */ + QStringList serviceTypes() const { return m_service->serviceTypes(); } + + bool supportsServiceType( const QString &serviceType ) const; + + // True if "Use index.html" is set (->the view doesn't necessarily show HTML!) + bool allowHTML() const { return m_bAllowHTML; } + void setAllowHTML( bool allow ) { m_bAllowHTML = allow; } + + // True if currently loading + bool isLoading() const { return m_bLoading; } + void setLoading( bool loading, bool hasPending = false ); + + // True if "locked to current location" (and their view mode, in fact) + bool isLockedLocation() const { return m_bLockedLocation; } + void setLockedLocation( bool b ); + + // True if can't be made active (e.g. dirtree). + bool isPassiveMode() const { return m_bPassiveMode; } + void setPassiveMode( bool mode ); + + // True if is hierarchical view + bool isHierarchicalView() const { return m_bHierarchicalView; } + void setHierarchicalView( bool mode ); + + // True if 'link' symbol set + bool isLinkedView() const { return m_bLinkedView; } + void setLinkedView( bool mode ); + + // True if toggle view + void setToggleView( bool b ) { m_bToggleView = b; } + bool isToggleView() const { return m_bToggleView; } + + // True if it always follows the active view + void setFollowActive(bool b) { m_bFollowActive = b; } + bool isFollowActive() { return m_bFollowActive; } + + // True if locked to current view mode + // Toggle views and passive views are locked to their view mode. + bool isLockedViewMode() const { return m_bToggleView || m_bPassiveMode; } + + // True if "builtin" (see X-KDE-BrowserView-Built-Into) + bool isBuiltinView() const { return m_bBuiltinView; } + + void setService( const KService::Ptr &s ) { m_service = s; } + KService::Ptr service() { return m_service; } + + QString caption() const { return m_caption; } + + KTrader::OfferList partServiceOffers() { return m_partServiceOffers; } + KTrader::OfferList appServiceOffers() { return m_appServiceOffers; } + + KonqMainWindow *mainWindow() const { return m_pMainWindow; } + + // return true if the method was found, false if the execution failed + bool callExtensionMethod( const char *methodName ); + bool callExtensionBoolMethod( const char *methodName, bool value ); + bool callExtensionStringMethod( const char *methodName, QString value ); + bool callExtensionURLMethod( const char *methodName, const KURL& value ); + + void setViewName( const QString &name ); + QString viewName() const; + + // True to enable the context popup menu + void enablePopupMenu( bool b ); + bool isPopupMenuEnabled() const { return m_bPopupMenuEnabled; } + + void reparseConfiguration(); + + void disableScrolling(); + + QStringList frameNames() const; + + KonqViewIface * dcopObject(); + + void goHistory( int steps ); + + // Set the KGlobal active instance (the one used by KBugReport) + void setActiveInstance(); + + // Called before reloading this view. Sets args.reload to true, and offers to repost form data. + // Returns false in case the reload must be cancelled. + bool prepareReload( KParts::URLArgs& args ); + + // overload for the QString version + void setLocationBarURL( const KURL& locationBarURL ); + + static QStringList childFrameNames( KParts::ReadOnlyPart *part ); + + static KParts::BrowserHostExtension *hostExtension( KParts::ReadOnlyPart *part, const QString &name ); + +signals: + + /** + * Signal the main window that the embedded part changed (e.g. because of changeViewMode) + */ + void sigPartChanged( KonqView *childView, KParts::ReadOnlyPart *oldPart, KParts::ReadOnlyPart *newPart ); + + /** + * Emitted in slotCompleted + */ + void viewCompleted( KonqView * view ); + + /** + * Emitted only if the option backRightClick is activated + */ + void backRightClick(); + +public slots: + /** + * Store location-bar URL in the child view + * and updates the main view if this view is the current one + * May be different from url e.g. if using "allowHTML". + */ + void setLocationBarURL( const QString & locationBarURL ); + /** + * get an icon for the URL from the BrowserExtension + */ + void setIconURL( const KURL &iconURL ); + + void setTabIcon( const KURL &url ); + + void setCaption( const QString & caption ); + + void setPageSecurity( int ); + + // connected to the KROP's KIO::Job + // but also to KonqRun's job + void slotInfoMessage( KIO::Job *, const QString &msg ); + +protected slots: + // connected to the KROP's KIO::Job + void slotStarted( KIO::Job * job ); + void slotCompleted(); + void slotCompleted( bool ); + void slotCanceled( const QString & errMsg ); + void slotPercent( KIO::Job *, unsigned long percent ); + void slotSpeed( KIO::Job *, unsigned long bytesPerSecond ); + + /** + * Connected to the BrowserExtension + */ + void slotSelectionInfo( const KFileItemList &items ); + void slotMouseOverInfo( const KFileItem* item ); + void slotOpenURLNotify(); + void slotEnableAction( const char * name, bool enabled ); + void slotSetActionText( const char* name, const QString& text ); + void slotMoveTopLevelWidget( int x, int y ); + void slotResizeTopLevelWidget( int w, int h ); + void slotRequestFocus(KParts::ReadOnlyPart*); + +private: + void enableBackRightClick( bool b ); + /** + * Replace the current view with a new view, created by @p viewFactory. + */ + void switchView( KonqViewFactory &viewFactory ); + + /** + * Connects the internal part to the main window. + * Do this after creating it and before inserting it. + */ + void connectPart(); + + /** + * Creates a new entry in the history. + */ + void createHistoryEntry(); + + /** + * Updates the current entry in the history. + * @param saveLocationBarURL whether to save the location bar URL as part of it + * (not done in openURL, to be able to revert if aborting) + */ + void updateHistoryEntry(bool saveLocationBarURL); + + void aboutToOpenURL( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + + void setServiceTypeInExtension(); + + void finishedWithCurrentURL(); + + virtual bool eventFilter( QObject *obj, QEvent *e ); + +////////////////// private members /////////////// + + KParts::ReadOnlyPart *m_pPart; + + QString m_sLocationBarURL; + QString m_sTypedURL; + KonqMainWindow::PageSecurity m_pageSecurity; + + /** + * The full history (back + current + forward) + * The current position in the history is m_lstHistory.current() + */ + QPtrList<HistoryEntry> m_lstHistory; + + /** + * The post data that _resulted_ in this page. + * e.g. when submitting a form, and the result is an image, this data will be + * set (and saved/restored) when the image is being viewed. Necessary for reload. + */ + QByteArray m_postData; + QString m_postContentType; + bool m_doPost; + + /** + * The referrer that was used to obtain this page. + */ + QString m_pageReferrer; + + KonqMainWindow *m_pMainWindow; + KonqRun *m_pRun; + KonqFrame *m_pKonqFrame; + + uint m_bAllowHTML:1; + uint m_bLoading:1; + uint m_bLockedLocation:1; + uint m_bPassiveMode:1; + uint m_bLinkedView:1; + uint m_bToggleView:1; + uint m_bLockHistory:1; + uint m_bAborted:1; + uint m_bGotIconURL:1; + uint m_bPopupMenuEnabled:1; + uint m_bFollowActive:1; + uint m_bPendingRedirection:1; + uint m_bBuiltinView:1; + uint m_bURLDropHandling:1; + uint m_bBackRightClick:1; + uint m_bHierarchicalView:1; + uint m_bDisableScrolling:1; + KTrader::OfferList m_partServiceOffers; + KTrader::OfferList m_appServiceOffers; + KService::Ptr m_service; + QString m_serviceType; + QString m_caption; + QString m_tempFile; + KonqViewIface * m_dcopObject; + KonqBrowserInterface *m_browserIface; + int m_randID; +}; + +#endif diff --git a/konqueror/konq_viewmgr.cc b/konqueror/konq_viewmgr.cc new file mode 100644 index 000000000..0460296c9 --- /dev/null +++ b/konqueror/konq_viewmgr.cc @@ -0,0 +1,1831 @@ +// -*- mode: c++; c-basic-offset: 2 -*- +/* This file is part of the KDE project + Copyright (C) 1999 Simon Hausmann <[email protected]> + + 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. + +*/ + +#include "konq_viewmgr.h" +#include "konq_view.h" +#include "konq_frame.h" +#include "konq_tabs.h" +#include "konq_profiledlg.h" +#include "konq_events.h" +#include "konq_settingsxt.h" + +#include <qfileinfo.h> +#include <qptrlist.h> + +#include <kaccelgen.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <kapplication.h> +#include <kglobalsettings.h> +#include <ktempfile.h> +#include <dcopclient.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include <assert.h> +#include <kpopupmenu.h> + +// #define DEBUG_VIEWMGR + +template class QPtrList<KonqView>; + +KonqViewManager::KonqViewManager( KonqMainWindow *mainWindow ) + : KParts::PartManager( mainWindow ) +{ + m_pMainWindow = mainWindow; + m_pDocContainer = 0L; + + m_pamProfiles = 0L; + m_bProfileListDirty = true; + m_bLoadingProfile = false; + + m_activePartChangedTimer = new QTimer(this); + connect(m_activePartChangedTimer, SIGNAL(timeout()), this, SLOT(emitActivePartChanged())); + connect( this, SIGNAL( activePartChanged ( KParts::Part * ) ), this, SLOT( slotActivePartChanged ( KParts::Part * ) ) ); +} + +KonqView* KonqViewManager::Initialize( const QString &serviceType, const QString &serviceName ) +{ + //kdDebug(1202) << "KonqViewManager::Initialize()" << endl; + KService::Ptr service; + KTrader::OfferList partServiceOffers, appServiceOffers; + KonqViewFactory newViewFactory = createView( serviceType, serviceName, service, partServiceOffers, appServiceOffers, true /*forceAutoEmbed*/ ); + if ( newViewFactory.isNull() ) + { + kdDebug(1202) << "KonqViewManager::Initialize() No suitable factory found." << endl; + return 0; + } + + KonqView* childView = setupView( m_pMainWindow, newViewFactory, service, partServiceOffers, appServiceOffers, serviceType, false ); + + setActivePart( childView->part() ); + m_pDocContainer = childView->frame(); + + convertDocContainer(); + static_cast<KonqFrameTabs*>( m_pDocContainer )->setAlwaysTabbedMode( + KonqSettings::alwaysTabbedMode() ); + + m_pDocContainer->widget()->show(); + return childView; +} + +KonqViewManager::~KonqViewManager() +{ + //kdDebug(1202) << "KonqViewManager::~KonqViewManager()" << endl; + clear(); +} + +KonqView* KonqViewManager::splitView ( Qt::Orientation orientation, + const QString &serviceType, + const QString &serviceName, + bool newOneFirst, bool forceAutoEmbed ) +{ +#ifdef DEBUG_VIEWMGR + kdDebug(1202) << "KonqViewManager::splitView(ServiceType)" << endl; + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); +#endif + + KonqFrame* splitFrame = m_pMainWindow->currentView()->frame(); + + KService::Ptr service; + KTrader::OfferList partServiceOffers, appServiceOffers; + + KonqViewFactory newViewFactory = createView( serviceType, serviceName, service, partServiceOffers, appServiceOffers, forceAutoEmbed ); + + if( newViewFactory.isNull() ) + return 0L; //do not split at all if we can't create the new view + + assert( splitFrame ); + + KonqFrameContainerBase* parentContainer = splitFrame->parentContainer(); + + bool moveNewContainer = false; + QValueList<int> splitterSizes; + int index= -1; + + if (parentContainer->frameType()=="Container") { + moveNewContainer = (static_cast<KonqFrameContainer*>(parentContainer)->idAfter( splitFrame->widget() ) != 0); + splitterSizes = static_cast<KonqFrameContainer*>(parentContainer)->sizes(); + } + else if (parentContainer->frameType()=="Tabs") + index = static_cast<KonqFrameTabs*>(parentContainer)->indexOf( splitFrame->widget() ); + +#ifndef NDEBUG + //printSizeInfo( splitFrame, parentContainer, "before split"); +#endif + + parentContainer->widget()->setUpdatesEnabled( false ); + + //kdDebug(1202) << "Move out child" << endl; + QPoint pos = splitFrame->widget()->pos(); + parentContainer->removeChildFrame( splitFrame ); + splitFrame->widget()->reparent( m_pMainWindow, pos ); + + //kdDebug(1202) << "Create new Container" << endl; + KonqFrameContainer *newContainer = new KonqFrameContainer( orientation, parentContainer->widget(), parentContainer ); + connect(newContainer,SIGNAL(ctrlTabPressed()),m_pMainWindow,SLOT(slotCtrlTabPressed())); + + parentContainer->insertChildFrame( newContainer, index ); + if ( moveNewContainer ) { + static_cast<KonqFrameContainer*>(parentContainer)->moveToFirst( newContainer ); + static_cast<KonqFrameContainer*>(parentContainer)->swapChildren(); + } + + //kdDebug(1202) << "Move in child" << endl; + splitFrame->widget()->reparent( newContainer, pos ); + newContainer->insertChildFrame( splitFrame ); + +#ifndef NDEBUG + //printSizeInfo( splitFrame, parentContainer, "after reparent" ); +#endif + + //kdDebug(1202) << "Create new child" << endl; + KonqView *newView = setupView( newContainer, newViewFactory, service, partServiceOffers, appServiceOffers, serviceType, false ); + +#ifndef DEBUG + //printSizeInfo( splitFrame, parentContainer, "after child insert" ); +#endif + + if ( newOneFirst ) + { + newContainer->moveToLast( splitFrame->widget() ); + newContainer->swapChildren(); + } + + QValueList<int> newSplitterSizes; + newSplitterSizes << 50 << 50; + newContainer->setSizes( newSplitterSizes ); + + if (parentContainer->frameType()=="Container") { + static_cast<KonqFrameContainer*>(parentContainer)->setSizes( splitterSizes ); + } + else if (parentContainer->frameType()=="Tabs") + static_cast<KonqFrameTabs*>(parentContainer)->showPage( newContainer ); + + splitFrame->show(); + //newView->frame()->show(); + newContainer->show(); + + parentContainer->widget()->setUpdatesEnabled( true ); + + if (m_pDocContainer == splitFrame) m_pDocContainer = newContainer; + + assert( newView->frame() ); + assert( newView->part() ); + newContainer->setActiveChild( newView->frame() ); + setActivePart( newView->part(), false ); + +#ifdef DEBUG_VIEWMGR + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); + kdDebug(1202) << "KonqViewManager::splitView(ServiceType) done" << endl; +#endif + + return newView; +} + +KonqView* KonqViewManager::splitWindow( Qt::Orientation orientation, + const QString &serviceType, + const QString &serviceName, + bool newOneFirst ) +{ + kdDebug(1202) << "KonqViewManager::splitWindow(default)" << endl; + + // Don't crash when doing things too quickly. + if (!m_pMainWindow || !m_pMainWindow->currentView()) + return 0L; + + KURL url = m_pMainWindow->currentView()->url(); + QString locationBarURL = m_pMainWindow->currentView()->locationBarURL(); + + KService::Ptr service; + KTrader::OfferList partServiceOffers, appServiceOffers; + + KonqViewFactory newViewFactory = createView( serviceType, serviceName, service, partServiceOffers, appServiceOffers ); + + if( newViewFactory.isNull() ) + return 0L; //do not split at all if we can't create the new view + + KonqFrameBase* mainFrame = m_pMainWindow->childFrame(); + + mainFrame->widget()->setUpdatesEnabled( false ); + + //kdDebug(1202) << "Move out child" << endl; + QPoint pos = mainFrame->widget()->pos(); + m_pMainWindow->removeChildFrame( mainFrame ); + + KonqFrameContainer *newContainer = new KonqFrameContainer( orientation, m_pMainWindow, 0L); + connect(newContainer,SIGNAL(ctrlTabPressed()),m_pMainWindow,SLOT(slotCtrlTabPressed())); + + m_pMainWindow->insertChildFrame( newContainer ); + + newContainer->insertChildFrame( mainFrame ); + mainFrame->widget()->reparent( newContainer, pos ); + + KonqView* childView = setupView( newContainer, newViewFactory, service, partServiceOffers, appServiceOffers, serviceType, true ); + + if( newOneFirst ) { + static_cast<KonqFrameContainer*>(newContainer)->moveToFirst( childView->frame() ); + static_cast<KonqFrameContainer*>(newContainer)->swapChildren(); + } + + newContainer->show(); + + mainFrame->widget()->setUpdatesEnabled( true ); + + if( childView ) + childView->openURL( url, locationBarURL ); + + newContainer->setActiveChild( mainFrame ); + +#ifdef DEBUG_VIEWMGR + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); + kdDebug(1202) << "KonqViewManager::splitWindow(default) done" << endl; +#endif + + return childView; +} + +void KonqViewManager::convertDocContainer() +{ + // Must create a tab container since one is not present, + // then insert the existing frame as a tab + + KonqFrameContainerBase* parentContainer = m_pDocContainer->parentContainer(); + + bool moveNewContainer = false; + QValueList<int> splitterSizes; + if (parentContainer->frameType()=="Container") { + moveNewContainer = (static_cast<KonqFrameContainer*>(parentContainer)->idAfter( m_pDocContainer->widget() ) != 0); + splitterSizes = static_cast<KonqFrameContainer*>(parentContainer)->sizes(); + } + + parentContainer->widget()->setUpdatesEnabled( false ); + + //kdDebug(1202) << "Move out child" << endl; + QPoint pos = m_pDocContainer->widget()->pos(); + parentContainer->removeChildFrame( m_pDocContainer ); + m_pDocContainer->widget()->reparent( m_pMainWindow, pos ); + + KonqFrameTabs* newContainer = new KonqFrameTabs( parentContainer->widget() , parentContainer, this); + parentContainer->insertChildFrame( newContainer ); + connect( newContainer, SIGNAL(ctrlTabPressed()), m_pMainWindow, SLOT(slotCtrlTabPressed()) ); + + m_pDocContainer->widget()->reparent( newContainer, pos ); + newContainer->insertChildFrame( m_pDocContainer ); + + if ( moveNewContainer ) { + static_cast<KonqFrameContainer*>(parentContainer)->moveToFirst( newContainer ); + static_cast<KonqFrameContainer*>(parentContainer)->swapChildren(); + } + if (parentContainer->frameType()=="Container") + static_cast<KonqFrameContainer*>(parentContainer)->setSizes( splitterSizes ); + + newContainer->show(); + + parentContainer->widget()->setUpdatesEnabled( true ); + + m_pDocContainer = newContainer; +} + +KonqView* KonqViewManager::addTab(const QString &serviceType, const QString &serviceName, bool passiveMode, bool openAfterCurrentPage ) +{ +#ifdef DEBUG_VIEWMGR + kdDebug(1202) << "------------- KonqViewManager::addTab starting -------------" << endl; + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); +#endif + + if (m_pDocContainer == 0L) + { + if (m_pMainWindow && + m_pMainWindow->currentView() && + m_pMainWindow->currentView()->frame()) { + m_pDocContainer = m_pMainWindow->currentView()->frame(); + } else { + kdDebug(1202) << "This view profile does not support tabs." << endl; + return 0L; + } + } + + KService::Ptr service; + KTrader::OfferList partServiceOffers, appServiceOffers; + + KonqViewFactory newViewFactory = createView( serviceType, serviceName, service, partServiceOffers, appServiceOffers, true /*forceAutoEmbed*/ ); + + if( newViewFactory.isNull() ) + return 0L; //do not split at all if we can't create the new view + + if (m_pDocContainer->frameType() != "Tabs") convertDocContainer(); + + KonqView* childView = setupView( static_cast<KonqFrameTabs*>(m_pDocContainer), newViewFactory, service, partServiceOffers, appServiceOffers, serviceType, passiveMode, openAfterCurrentPage ); + +#ifdef DEBUG_VIEWMGR + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); + kdDebug(1202) << "------------- KonqViewManager::addTab done -------------" << endl; +#endif + + return childView; +} + +KonqView* KonqViewManager::addTabFromHistory( int steps, bool openAfterCurrentPage ) +{ + if (m_pDocContainer == 0L) + { + if (m_pMainWindow && + m_pMainWindow->currentView() && + m_pMainWindow->currentView()->frame()) { + m_pDocContainer = m_pMainWindow->currentView()->frame(); + } else { + kdDebug(1202) << "This view profile does not support tabs." << endl; + return 0L; + } + } + if (m_pDocContainer->frameType() != "Tabs") convertDocContainer(); + + int oldPos = m_pMainWindow->currentView()->historyPos(); + int newPos = oldPos + steps; + + const HistoryEntry * he = m_pMainWindow->currentView()->historyAt(newPos); + if(!he) + return 0L; + + KonqView* newView = 0L; + newView = addTab( he->strServiceType, he->strServiceName, false, openAfterCurrentPage ); + + if(!newView) + return 0L; + + newView->copyHistory(m_pMainWindow->currentView()); + newView->setHistoryPos(newPos); + newView->restoreHistory(); + + return newView; +} + + +void KonqViewManager::duplicateTab( KonqFrameBase* tab, bool openAfterCurrentPage ) +{ +#ifdef DEBUG_VIEWMGR + kdDebug(1202) << "---------------- KonqViewManager::duplicateTab( " << tab << " ) --------------" << endl; + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); +#endif + + if (m_pDocContainer == 0L) + { + if (m_pMainWindow && + m_pMainWindow->currentView() && + m_pMainWindow->currentView()->frame()) { + m_pDocContainer = m_pMainWindow->currentView()->frame(); + } else { + kdDebug(1202) << "This view profile does not support tabs." << endl; + return; + } + } + + if (m_pDocContainer->frameType() != "Tabs") convertDocContainer(); + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + + KonqFrameBase* currentFrame; + if ( tab == 0L ) + currentFrame = dynamic_cast<KonqFrameBase*>(tabContainer->currentPage()); + else + currentFrame = tab; + + if (!currentFrame) { + return; + } + + KTempFile tempFile; + tempFile.setAutoDelete( true ); + KConfig config( tempFile.name() ); + config.setGroup( "View Profile" ); + + QString prefix = QString::fromLatin1( currentFrame->frameType() ) + QString::number(0); + config.writeEntry( "RootItem", prefix ); + prefix.append( '_' ); + currentFrame->saveConfig( &config, prefix, true, 0L, 0, 1); + + QString rootItem = config.readEntry( "RootItem", "empty" ); + + if (rootItem.isNull() || rootItem == "empty") return; + + // This flag is used by KonqView, to distinguish manual view creation + // from profile loading (e.g. in switchView) + m_bLoadingProfile = true; + + loadItem( config, tabContainer, rootItem, KURL(""), true, openAfterCurrentPage ); + + m_bLoadingProfile = false; + + m_pMainWindow->enableAllActions(true); + + // This flag disables calls to viewCountChanged while creating the views, + // so we do it once at the end : + m_pMainWindow->viewCountChanged(); + + if (openAfterCurrentPage) + tabContainer->setCurrentPage( tabContainer->currentPageIndex () + 1 ); + else + tabContainer->setCurrentPage( tabContainer->count() - 1 ); + + KonqFrameBase* duplicatedFrame = dynamic_cast<KonqFrameBase*>(tabContainer->currentPage()); + if (duplicatedFrame) + duplicatedFrame->copyHistory( currentFrame ); + +#ifdef DEBUG_VIEWMGR + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); + kdDebug(1202) << "------------- KonqViewManager::duplicateTab done --------------" << endl; +#endif +} + +void KonqViewManager::breakOffTab( KonqFrameBase* tab ) +{ +#ifdef DEBUG_VIEWMGR + kdDebug(1202) << "---------------- KonqViewManager::breakOffTab( " << tab << " ) --------------" << endl; + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); +#endif + + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + + int width = m_pMainWindow->width(); + int height = m_pMainWindow->height(); + + KonqFrameBase* currentFrame; + if ( tab == 0L ) + currentFrame = dynamic_cast<KonqFrameBase*>(tabContainer->currentPage()); + else + currentFrame = tab; + + if (!currentFrame) { + return; + } + + KTempFile tempFile; + tempFile.setAutoDelete( true ); + KConfig config( tempFile.name() ); + config.setGroup( "View Profile" ); + + QString prefix = QString::fromLatin1( currentFrame->frameType() ) + QString::number(0); + config.writeEntry( "RootItem", prefix ); + prefix.append( '_' ); + config.writeEntry( QString::fromLatin1( "docContainer" ).prepend( prefix ), true ); + currentFrame->saveConfig( &config, prefix, true, 0L, 0, 1); + + KonqMainWindow *mainWindow = new KonqMainWindow( KURL(), false ); + if (mainWindow == 0L) return; + + mainWindow->viewManager()->loadViewProfile( config, "" ); + + KonqFrameBase * newDocContainer = mainWindow->viewManager()->docContainer(); + if( newDocContainer && newDocContainer->frameType() == "Tabs") + { + KonqFrameTabs *kft = static_cast<KonqFrameTabs *>(newDocContainer); + KonqFrameBase *newFrame = dynamic_cast<KonqFrameBase*>(kft->currentPage()); + if(newFrame) + newFrame->copyHistory( currentFrame ); + } + + removeTab( currentFrame ); + + mainWindow->enableAllActions( true ); + + mainWindow->resize( width, height ); + + mainWindow->activateChild(); + + mainWindow->show(); + +#ifdef DEBUG_VIEWMGR + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); + + mainWindow->dumpViewList(); + mainWindow->viewManager()->printFullHierarchy( mainWindow ); + + kdDebug(1202) << "------------- KonqViewManager::breakOffTab done --------------" << endl; +#endif +} + +void KonqViewManager::removeTab( KonqFrameBase* tab ) +{ +#ifdef DEBUG_VIEWMGR + kdDebug(1202) << "---------------- KonqViewManager::removeTab( " << tab << " ) --------------" << endl; + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); +#endif + + if (m_pDocContainer == 0L) + return; + if (m_pDocContainer->frameType() != "Tabs" ) + return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + + KonqFrameBase* currentFrame; + if ( tab != 0L ) { + currentFrame = tab; + } else { + currentFrame = dynamic_cast<KonqFrameBase*>(tabContainer->currentPage()); + if (!currentFrame) { + return; + } + } + + if ( tabContainer->count() == 1 ) + return; + + if (currentFrame->widget() == tabContainer->currentPage()) + setActivePart( 0L, true ); + + tabContainer->removeChildFrame(currentFrame); + + QPtrList<KonqView> viewList; + QPtrListIterator<KonqView> it( viewList ); + + currentFrame->listViews( &viewList ); + + for ( it.toFirst(); it != 0L; ++it ) + { + if (it.current() == m_pMainWindow->currentView()) + setActivePart( 0L, true ); + m_pMainWindow->removeChildView( it.current() ); + delete it.current(); + } + + delete currentFrame; + + tabContainer->slotCurrentChanged(tabContainer->currentPage()); + +#ifdef DEBUG_VIEWMGR + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); + kdDebug(1202) << "------------- KonqViewManager::removeTab done --------------" << endl; +#endif +} + +void KonqViewManager::reloadAllTabs( ) +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + + QPtrList<KonqFrameBase> frameList = *tabContainer->childFrameList(); + QPtrListIterator<KonqFrameBase> it( frameList ); + + for ( it.toFirst(); it != 0L; ++it ) + { + if ( it.current()->activeChildView()) + { + if( !it.current()->activeChildView()->locationBarURL().isEmpty()) + it.current()->activeChildView()->openURL( it.current()->activeChildView()->url(),it.current()->activeChildView()->locationBarURL()); + } + } +} + +void KonqViewManager::removeOtherTabs( KonqFrameBase* tab ) +{ + + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + + KonqFrameBase *currentFrame; + + if ( tab == 0L ) + currentFrame = dynamic_cast<KonqFrameBase*>(tabContainer->currentPage()); + else + currentFrame = tab; + + if (!currentFrame) { + return; + } + + QPtrList<KonqFrameBase> frameList = *tabContainer->childFrameList(); + QPtrListIterator<KonqFrameBase> it( frameList ); + + for ( it.toFirst(); it != 0L; ++it ) + { + if( it.current() != currentFrame ) + removeTab(it.current()); + } + +} + +void KonqViewManager::moveTabBackward() +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + if( tabContainer->count() == 1 ) return; + + int iTab = tabContainer->currentPageIndex(); + kdDebug()<<" tabContainer->currentPageIndex(); :"<<iTab<<endl; + tabContainer->moveTabBackward(iTab); +} + +void KonqViewManager::moveTabForward() +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + if( tabContainer->count() == 1 ) return; + + int iTab = tabContainer->currentPageIndex(); + tabContainer->moveTabForward(iTab); +} + +void KonqViewManager::activateNextTab() +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + if( tabContainer->count() == 1 ) return; + + int iTab = tabContainer->currentPageIndex(); + + iTab++; + + if( iTab == tabContainer->count() ) + iTab = 0; + + tabContainer->setCurrentPage( iTab ); +} + +void KonqViewManager::activatePrevTab() +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + if( tabContainer->count() == 1 ) return; + + int iTab = tabContainer->currentPageIndex(); + + iTab--; + + if( iTab == -1 ) + iTab = tabContainer->count() - 1; + + tabContainer->setCurrentPage( iTab ); +} + +void KonqViewManager::activateTab(int position) +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + if (position<0 || tabContainer->count() == 1 || position>=tabContainer->count()) return; + + tabContainer->setCurrentPage( position ); +} + +void KonqViewManager::showTab( KonqView *view ) +{ + KonqFrameTabs *tabContainer = static_cast<KonqFrameTabs*>( docContainer() ); + if (tabContainer->currentPage() != view->frame()) + { + tabContainer->showPage( view->frame() ); + emitActivePartChanged(); + } +} + +void KonqViewManager::updatePixmaps() +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + + QPtrList<KonqView> viewList; + QPtrListIterator<KonqView> it( viewList ); + + tabContainer->listViews( &viewList ); + for ( it.toFirst(); it != 0L; ++it ) + it.current()->setTabIcon( KURL::fromPathOrURL( it.current()->locationBarURL() ) ); +} + +void KonqViewManager::removeView( KonqView *view ) +{ +#ifdef DEBUG_VIEWMGR + kdDebug(1202) << "---------------- removeView --------------" << view << endl; + m_pMainWindow->dumpViewList(); + printFullHierarchy( m_pMainWindow ); +#endif + + if (!view) + return; + + KonqFrame* frame = view->frame(); + KonqFrameContainerBase* parentContainer = frame->parentContainer(); + + kdDebug(1202) << "view=" << view << " frame=" << frame << " parentContainer=" << parentContainer << endl; + + if (parentContainer->frameType()=="Container") + { + kdDebug(1202) << "parentContainer is a KonqFrameContainer" << endl; + + KonqFrameContainerBase* grandParentContainer = parentContainer->parentContainer(); + kdDebug(1202) << "grandParentContainer=" << grandParentContainer << endl; + + setActivePart( 0L, true ); + + int index = -1; + QValueList<int> splitterSizes; + bool moveOtherChild = false; + + if (grandParentContainer->frameType()=="Tabs") + index = static_cast<KonqFrameTabs*>(grandParentContainer)->indexOf( parentContainer->widget() ); + else if (grandParentContainer->frameType()=="Container") + { + moveOtherChild = (static_cast<KonqFrameContainer*>(grandParentContainer)->idAfter( parentContainer->widget() ) != 0); + splitterSizes = static_cast<KonqFrameContainer*>(grandParentContainer)->sizes(); + } + + KonqFrameBase* otherFrame = static_cast<KonqFrameContainer*>(parentContainer)->otherChild( frame ); + kdDebug(1202) << "otherFrame=" << otherFrame << endl; + + if( otherFrame == 0L ) + { + kdWarning(1202) << "KonqViewManager::removeView: This shouldn't happen!" << endl; + return; + } + + if (m_pDocContainer == parentContainer) m_pDocContainer = otherFrame; + + grandParentContainer->widget()->setUpdatesEnabled( false ); + static_cast<KonqFrameContainer*>(parentContainer)->setAboutToBeDeleted(); + + //kdDebug(1202) << "--- Reparenting otherFrame to m_pMainWindow " << m_pMainWindow << endl; + QPoint pos = otherFrame->widget()->pos(); + otherFrame->reparentFrame( m_pMainWindow, pos ); + + //kdDebug(1202) << "--- Removing otherFrame from parentContainer" << endl; + parentContainer->removeChildFrame( otherFrame ); + + //kdDebug(1202) << "--- Removing parentContainer from grandParentContainer" << endl; + grandParentContainer->removeChildFrame( parentContainer ); + + //kdDebug(1202) << "--- Removing view from view list" << endl; + m_pMainWindow->removeChildView(view); + //kdDebug(1202) << "--- Deleting view " << view << endl; + delete view; // This deletes the view, which deletes the part, which deletes its widget + + //kdDebug(1202) << "--- Deleting parentContainer " << parentContainer + // << ". Its parent is " << parentContainer->widget()->parent() << endl; + delete parentContainer; + + //kdDebug(1202) << "--- Reparenting otherFrame to grandParentContainer" << grandParentContainer << endl; + otherFrame->reparentFrame( grandParentContainer->widget(), pos ); + + //kdDebug(1202) << "--- Inserting otherFrame into grandParentContainer" << grandParentContainer << endl; + grandParentContainer->insertChildFrame( otherFrame, index ); + + if( moveOtherChild ) + { + static_cast<KonqFrameContainer*>(grandParentContainer)->moveToFirst( otherFrame->widget() ); + static_cast<KonqFrameContainer*>(grandParentContainer)->swapChildren(); + } + + if (grandParentContainer->frameType()=="Container") + static_cast<KonqFrameContainer*>(grandParentContainer)->setSizes( splitterSizes ); + + otherFrame->widget()->show(); + + grandParentContainer->setActiveChild( otherFrame ); + grandParentContainer->activateChild(); + + grandParentContainer->widget()->setUpdatesEnabled( true ); + } + else if (parentContainer->frameType()=="Tabs") { + kdDebug(1202) << "parentContainer " << parentContainer << " is a KonqFrameTabs" << endl; + + removeTab( frame ); + } + else if (parentContainer->frameType()=="MainWindow") + kdDebug(1202) << "parentContainer is a KonqMainWindow. This shouldn't be removeable, not removing." << endl; + else + kdDebug(1202) << "Unrecognized frame type, not removing." << endl; + +#ifdef DEBUG_VIEWMGR + printFullHierarchy( m_pMainWindow ); + m_pMainWindow->dumpViewList(); + + kdDebug(1202) << "------------- removeView done --------------" << view << endl; +#endif +} + +// reimplemented from PartManager +void KonqViewManager::removePart( KParts::Part * part ) +{ + kdDebug(1202) << "KonqViewManager::removePart ( " << part << " )" << endl; + // This is called when a part auto-deletes itself (case 1), or when + // the "delete view" above deletes, in turn, the part (case 2) + + kdDebug(1202) << "Calling KParts::PartManager::removePart " << part << endl; + KParts::PartManager::removePart( part ); + + // If we were called by PartManager::slotObjectDestroyed, then the inheritance has + // been deleted already... Can't use inherits(). + + KonqView * view = m_pMainWindow->childView( static_cast<KParts::ReadOnlyPart *>(part) ); + if ( view ) // the child view still exists, so we are in case 1 + { + kdDebug(1202) << "Found a child view" << endl; + view->partDeleted(); // tell the child view that the part auto-deletes itself + if (m_pMainWindow->mainViewsCount() == 1) + { + kdDebug(1202) << "Deleting last view -> closing the window" << endl; + clear(); + kdDebug(1202) << "Closing m_pMainWindow " << m_pMainWindow << endl; + m_pMainWindow->close(); // will delete it + return; + } else { // normal case + removeView( view ); + } + } + + kdDebug(1202) << "KonqViewManager::removePart ( " << part << " ) done" << endl; +} + +void KonqViewManager::slotPassiveModePartDeleted() +{ + // Passive mode parts aren't registered to the part manager, + // so we have to handle suicidal ones ourselves + KParts::ReadOnlyPart * part = const_cast<KParts::ReadOnlyPart *>( static_cast<const KParts::ReadOnlyPart *>( sender() ) ); + disconnect( part, SIGNAL( destroyed() ), this, SLOT( slotPassiveModePartDeleted() ) ); + kdDebug(1202) << "KonqViewManager::slotPassiveModePartDeleted part=" << part << endl; + KonqView * view = m_pMainWindow->childView( part ); + kdDebug(1202) << "view=" << view << endl; + if ( view != 0L) // the child view still exists, so the part suicided + { + view->partDeleted(); // tell the child view that the part deleted itself + removeView( view ); + } +} + +void KonqViewManager::viewCountChanged() +{ + bool bShowActiveViewIndicator = ( m_pMainWindow->viewCount() > 1 ); + bool bShowLinkedViewIndicator = ( m_pMainWindow->linkableViewsCount() > 1 ); + + KonqMainWindow::MapViews mapViews = m_pMainWindow->viewMap(); + KonqMainWindow::MapViews::Iterator it = mapViews.begin(); + KonqMainWindow::MapViews::Iterator end = mapViews.end(); + for ( ; it != end ; ++it ) + { + KonqFrameStatusBar* sb = it.data()->frame()->statusbar(); + sb->showActiveViewIndicator( bShowActiveViewIndicator && !it.data()->isPassiveMode() ); + sb->showLinkedViewIndicator( bShowLinkedViewIndicator && !it.data()->isFollowActive() ); + } +} + +void KonqViewManager::clear() +{ + kdDebug(1202) << "KonqViewManager::clear" << endl; + setActivePart( 0L, true /* immediate */ ); + + if (m_pMainWindow->childFrame() == 0L) return; + + QPtrList<KonqView> viewList; + + m_pMainWindow->listViews( &viewList ); + + kdDebug(1202) << viewList.count() << " items" << endl; + + QPtrListIterator<KonqView> it( viewList ); + for ( it.toFirst(); it.current(); ++it ) { + m_pMainWindow->removeChildView( it.current() ); + kdDebug(1202) << "Deleting " << it.current() << endl; + delete it.current(); + } + + kdDebug(1202) << "deleting mainFrame " << endl; + KonqFrameBase* frame = m_pMainWindow->childFrame(); + m_pMainWindow->removeChildFrame( frame ); // will set childFrame() to NULL + delete frame; + + m_pDocContainer = 0L; +} + +KonqView *KonqViewManager::chooseNextView( KonqView *view ) +{ + //kdDebug(1202) << "KonqViewManager(" << this << ")::chooseNextView(" << view << ")" << endl; + KonqMainWindow::MapViews mapViews = m_pMainWindow->viewMap(); + + KonqMainWindow::MapViews::Iterator it = mapViews.begin(); + KonqMainWindow::MapViews::Iterator end = mapViews.end(); + if ( view ) // find it in the map - can't use the key since view->part() might be 0L + while ( it != end && it.data() != view ) + ++it; + + // the view should always be in the list + if ( it == end ) { + if ( view ) + kdWarning() << "View " << view << " is not in list !" << endl; + it = mapViews.begin(); + if ( it == end ) + return 0L; // We have no view at all - this used to happen with totally-empty-profiles + } + + KonqMainWindow::MapViews::Iterator startIt = it; + + //kdDebug(1202) << "KonqViewManager::chooseNextView: count=" << mapViews.count() << endl; + while ( true ) + { + //kdDebug(1202) << "*KonqViewManager::chooseNextView going next" << endl; + if ( ++it == end ) // move to next + it = mapViews.begin(); // rewind on end + + if ( it == startIt && view ) + break; // no next view found + + KonqView *nextView = it.data(); + if ( nextView && !nextView->isPassiveMode() ) + return nextView; + //kdDebug(1202) << "KonqViewManager::chooseNextView nextView=" << nextView << " passive=" << nextView->isPassiveMode() << endl; + } + + //kdDebug(1202) << "KonqViewManager::chooseNextView: returning 0L" << endl; + return 0L; // no next view found +} + +KonqViewFactory KonqViewManager::createView( const QString &serviceType, + const QString &serviceName, + KService::Ptr &service, + KTrader::OfferList &partServiceOffers, + KTrader::OfferList &appServiceOffers, + bool forceAutoEmbed ) +{ + kdDebug(1202) << "KonqViewManager::createView" << endl; + KonqViewFactory viewFactory; + + if( serviceType.isEmpty() && m_pMainWindow->currentView() ) { + //clone current view + KonqView *cv = m_pMainWindow->currentView(); + QString _serviceType, _serviceName; + if ( cv->service()->desktopEntryName() == "konq_sidebartng" ) { + _serviceType = "text/html"; + } + else { + _serviceType = cv->serviceType(); + _serviceName = cv->service()->desktopEntryName(); + } + + viewFactory = KonqFactory::createView( _serviceType, _serviceName, + &service, &partServiceOffers, &appServiceOffers, forceAutoEmbed ); + } + else { + //create view with the given servicetype + viewFactory = KonqFactory::createView( serviceType, serviceName, + &service, &partServiceOffers, &appServiceOffers, forceAutoEmbed ); + } + + return viewFactory; +} + +KonqView *KonqViewManager::setupView( KonqFrameContainerBase *parentContainer, + KonqViewFactory &viewFactory, + const KService::Ptr &service, + const KTrader::OfferList &partServiceOffers, + const KTrader::OfferList &appServiceOffers, + const QString &serviceType, + bool passiveMode, + bool openAfterCurrentPage ) +{ + kdDebug(1202) << "KonqViewManager::setupView passiveMode=" << passiveMode << endl; + + QString sType = serviceType; + + if ( sType.isEmpty() ) + sType = m_pMainWindow->currentView()->serviceType(); + + //kdDebug(1202) << "KonqViewManager::setupView creating KonqFrame with parent=" << parentContainer << endl; + KonqFrame* newViewFrame = new KonqFrame( parentContainer->widget(), parentContainer, "KonqFrame" ); + newViewFrame->setGeometry( 0, 0, m_pMainWindow->width(), m_pMainWindow->height() ); + + //kdDebug(1202) << "Creating KonqView" << endl; + KonqView *v = new KonqView( viewFactory, newViewFrame, + m_pMainWindow, service, partServiceOffers, appServiceOffers, sType, passiveMode ); + //kdDebug(1202) << "KonqView created - v=" << v << " v->part()=" << v->part() << endl; + + QObject::connect( v, SIGNAL( sigPartChanged( KonqView *, KParts::ReadOnlyPart *, KParts::ReadOnlyPart * ) ), + m_pMainWindow, SLOT( slotPartChanged( KonqView *, KParts::ReadOnlyPart *, KParts::ReadOnlyPart * ) ) ); + + m_pMainWindow->insertChildView( v ); + + + int index = -1; + + if (m_pDocContainer && m_pDocContainer->frameType() == "Tabs") + { + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + if ( openAfterCurrentPage ) + index = tabContainer->currentPageIndex() +1 ; + } + + parentContainer->insertChildFrame( newViewFrame, index ); + + if (parentContainer->frameType() != "Tabs") newViewFrame->show(); + + // Don't register passive views to the part manager + if ( !v->isPassiveMode() ) // note that KonqView's constructor could set this to true even if passiveMode is false + addPart( v->part(), false ); + else + { + // Passive views aren't registered, but we still want to detect the suicidal ones + connect( v->part(), SIGNAL( destroyed() ), this, SLOT( slotPassiveModePartDeleted() ) ); + } + + //kdDebug(1202) << "KonqViewManager::setupView done" << endl; + return v; +} + +///////////////// Profile stuff //////////////// + +void KonqViewManager::saveViewProfile( const QString & fileName, const QString & profileName, bool saveURLs, bool saveWindowSize ) +{ + + QString path = locateLocal( "data", QString::fromLatin1( "konqueror/profiles/" ) + + fileName, KGlobal::instance() ); + + if ( QFile::exists( path ) ) + QFile::remove( path ); + + KSimpleConfig cfg( path ); + cfg.setGroup( "Profile" ); + if ( !profileName.isEmpty() ) + cfg.writePathEntry( "Name", profileName ); + + saveViewProfile( cfg, saveURLs, saveWindowSize ); + +} + +void KonqViewManager::saveViewProfile( KConfig & cfg, bool saveURLs, bool saveWindowSize ) +{ + //kdDebug(1202) << "KonqViewManager::saveViewProfile" << endl; + if( m_pMainWindow->childFrame() != 0L ) { + QString prefix = QString::fromLatin1( m_pMainWindow->childFrame()->frameType() ) + + QString::number(0); + cfg.writeEntry( "RootItem", prefix ); + prefix.append( '_' ); + m_pMainWindow->saveConfig( &cfg, prefix, saveURLs, m_pDocContainer, 0, 1); + } + + cfg.writeEntry( "FullScreen", m_pMainWindow->fullScreenMode()); + cfg.writeEntry("XMLUIFile", m_pMainWindow->xmlFile()); + if ( saveWindowSize ) + { + cfg.writeEntry( "Width", m_pMainWindow->width() ); + cfg.writeEntry( "Height", m_pMainWindow->height() ); + } + + // Save menu/toolbar settings in profile. Relys on konq_mainwindow calling + // setAutoSaveSetting( "KongMainWindow", false ). The false is important, + // we do not want this call save size settings in the profile, because we + // do it ourselves. Save in a separate group than the rest of the profile. + QString savedGroup = cfg.group(); + m_pMainWindow->saveMainWindowSettings( &cfg, "Main Window Settings" ); + cfg.setGroup( savedGroup ); + + cfg.sync(); +} + +void KonqViewManager::loadViewProfile( const QString & path, const QString & filename, + const KURL & forcedURL, const KonqOpenURLRequest &req, + bool resetWindow, bool openURL ) +{ + KConfig cfg( path, true ); + cfg.setDollarExpansion( true ); + cfg.setGroup( "Profile" ); + loadViewProfile( cfg, filename, forcedURL, req, resetWindow, openURL ); +} + +void KonqViewManager::loadViewProfile( KConfig &cfg, const QString & filename, + const KURL & forcedURL, const KonqOpenURLRequest &req, + bool resetWindow, bool openURL ) +{ + if ( docContainer() && docContainer()->frameType()=="Tabs" ) + { + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(docContainer()); + if ( tabContainer->count() > 1 ) + { + if ( KMessageBox::warningContinueCancel( 0, + i18n("You have multiple tabs open in this window.\n" + "Loading a view profile will close them."), + i18n("Confirmation"), + i18n("Load View Profile"), + "LoadProfileTabsConfirm" ) == KMessageBox::Cancel ) + return; + } + + KonqView *originalView = m_pMainWindow->currentView(); + QPtrList<KonqFrameBase> frameList = *tabContainer->childFrameList(); + QPtrListIterator<KonqFrameBase> it( frameList ); + for ( it.toFirst(); it != 0L; ++it ) + { + KonqView *view = it.current()->activeChildView(); + if (view && view->part() && (view->part()->metaObject()->findProperty("modified") != -1)) { + QVariant prop = view->part()->property("modified"); + if (prop.isValid() && prop.toBool()) { + showTab( view ); + if ( KMessageBox::warningContinueCancel( 0, + i18n("This tab contains changes that have not been submitted.\nLoading a profile will discard these changes."), + i18n("Discard Changes?"), i18n("&Discard Changes"), "discardchangesloadprofile") != KMessageBox::Continue ) + { + showTab( originalView ); + return; + } + } + } + } + showTab( originalView ); + } + else + { + KonqView *view = m_pMainWindow->currentView(); + if (view && view->part() && (view->part()->metaObject()->findProperty("modified") != -1)) { + QVariant prop = view->part()->property("modified"); + if (prop.isValid() && prop.toBool()) + if ( KMessageBox::warningContinueCancel( 0, + i18n("This page contains changes that have not been submitted.\nLoading a profile will discard these changes."), + i18n("Discard Changes?"), i18n("&Discard Changes"), "discardchangesloadprofile") != KMessageBox::Continue ) + return; + } + } + + bool alwaysTabbedMode = KonqSettings::alwaysTabbedMode(); + + m_currentProfile = filename; + m_currentProfileText = cfg.readPathEntry("Name",filename); + m_profileHomeURL = cfg.readEntry("HomeURL", QString::null); + + m_pMainWindow->currentProfileChanged(); + KURL defaultURL; + if ( m_pMainWindow->currentView() ) + defaultURL = m_pMainWindow->currentView()->url(); + + clear(); + + QString rootItem = cfg.readEntry( "RootItem", "empty" ); + + //kdDebug(1202) << "KonqViewManager::loadViewProfile : loading RootItem " << rootItem << + //" forcedURL " << forcedURL.url() << endl; + + if ( forcedURL.url() != "about:blank" ) + { + // This flag is used by KonqView, to distinguish manual view creation + // from profile loading (e.g. in switchView) + m_bLoadingProfile = true; + + loadItem( cfg, m_pMainWindow, rootItem, defaultURL, openURL && forcedURL.isEmpty() ); + + m_bLoadingProfile = false; + + m_pMainWindow->enableAllActions(true); + + // This flag disables calls to viewCountChanged while creating the views, + // so we do it once at the end : + m_pMainWindow->viewCountChanged(); + } + else + { + m_pMainWindow->disableActionsNoView(); + m_pMainWindow->action( "clear_location" )->activate(); + } + + //kdDebug(1202) << "KonqViewManager::loadViewProfile : after loadItem " << endl; + + if (m_pDocContainer == 0L) + { + if (m_pMainWindow && + m_pMainWindow->currentView() && + m_pMainWindow->currentView()->frame()) { + m_pDocContainer = m_pMainWindow->currentView()->frame(); + } else { + kdDebug(1202) << "This view profile does not support tabs." << endl; + return; + } + } + + + if ( m_pDocContainer->frameType() != "Tabs") + convertDocContainer(); + + static_cast<KonqFrameTabs*>( m_pDocContainer )->setAlwaysTabbedMode( alwaysTabbedMode ); + + // Set an active part first so that we open the URL in the current view + // (to set the location bar correctly and asap) + KonqView *nextChildView = 0L; + nextChildView = m_pMainWindow->activeChildView(); + if (nextChildView == 0L) nextChildView = chooseNextView( 0L ); + setActivePart( nextChildView ? nextChildView->part() : 0L, true /* immediate */); + + // #71164 + if ( !req.args.frameName.isEmpty() && nextChildView ) { + nextChildView->setViewName( req.args.frameName ); + } + + if ( openURL && !forcedURL.isEmpty()) + { + KonqOpenURLRequest _req(req); + _req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); + _req.forceAutoEmbed = true; // it's a new window, let's use it + + m_pMainWindow->openURL( nextChildView /* can be 0 for an empty profile */, + forcedURL, _req.args.serviceType, _req, _req.args.trustedSource ); + + // TODO choose a linked view if any (instead of just the first one), + // then open the same URL in any non-linked one + } + else + { + if ( m_pMainWindow->locationBarURL().isEmpty() ) // No URL -> the user will want to type one + m_pMainWindow->focusLocationBar(); + } + + // Window size + if ( !m_pMainWindow->initialGeometrySet() ) + { + if (cfg.readBoolEntry( "FullScreen" )) + { + // Full screen on + m_pMainWindow->showFullScreen(); + } + else + { + // Full screen off + if( m_pMainWindow->isFullScreen()) + m_pMainWindow->showNormal(); + + QSize size = readConfigSize( cfg, m_pMainWindow ); + if ( size.isValid() ) + m_pMainWindow->resize( size ); + else // no size in the profile; use last known size + m_pMainWindow->restoreWindowSize(); + } + } + + if( resetWindow ) + { // force default settings for the GUI + m_pMainWindow->applyMainWindowSettings( KGlobal::config(), "KonqMainWindow", true ); + } + + // Apply menu/toolbar settings saved in profile. Read from a separate group + // so that the window doesn't try to change the size stored in the Profile group. + // (If applyMainWindowSettings finds a "Width" or "Height" entry, it + // sets them to 0,0) + QString savedGroup = cfg.group(); + m_pMainWindow->applyMainWindowSettings( &cfg, "Main Window Settings" ); + cfg.setGroup( savedGroup ); + +#ifdef DEBUG_VIEWMGR + printFullHierarchy( m_pMainWindow ); +#endif + + //kdDebug(1202) << "KonqViewManager::loadViewProfile done" << endl; +} + +void KonqViewManager::setActivePart( KParts::Part *part, QWidget * ) +{ + setActivePart( part, false ); +} + +void KonqViewManager::setActivePart( KParts::Part *part, bool immediate ) +{ + //kdDebug(1202) << "KonqViewManager::setActivePart " << part << endl; + //if ( part ) + // kdDebug(1202) << " " << part->className() << " " << part->name() << endl; + + // Due to the single-shot timer below, we need to also make sure that + // the mainwindow also has the right part active already + KParts::Part* mainWindowActivePart = (m_pMainWindow && m_pMainWindow->currentView()) + ? m_pMainWindow->currentView()->part() : 0; + if (part == activePart() && (!immediate || mainWindowActivePart == part)) + { + if ( part ) + kdDebug(1202) << "Part is already active!" << endl; + return; + } + + // Don't activate when part changed in non-active tab + KonqView* partView = m_pMainWindow->childView((KParts::ReadOnlyPart*)part); + if (partView) + { + KonqFrameContainerBase* parentContainer = partView->frame()->parentContainer(); + if (parentContainer->frameType()=="Tabs") + { + KonqFrameTabs* parentFrameTabs = static_cast<KonqFrameTabs*>(parentContainer); + if (partView->frame() != parentFrameTabs->currentPage()) + return; + } + } + + if (m_pMainWindow && m_pMainWindow->currentView()) + m_pMainWindow->currentView()->setLocationBarURL(m_pMainWindow->locationBarURL()); + + KParts::PartManager::setActivePart( part ); + + if (part && part->widget()) + part->widget()->setFocus(); + + if (!immediate && reason() != ReasonRightClick) { + // We use a 0s single shot timer so that when left-clicking on a part, + // we process the mouse event before rebuilding the GUI. + // Otherwise, when e.g. dragging icons, the mouse pointer can already + // be very far from where it was... + m_activePartChangedTimer->start( 0, true ); + // This is not done with right-clicking so that the part is activated before the + // popup appears (#75201) + } else { + emitActivePartChanged(); + } +} + +void KonqViewManager::slotActivePartChanged ( KParts::Part *newPart ) +{ + //kdDebug(1202) << "KonqViewManager::slotActivePartChanged " << newPart << endl; + if (newPart == 0L) { + //kdDebug(1202) << "newPart = 0L , returning" << endl; + return; + } + KonqView * view = m_pMainWindow->childView( static_cast<KParts::ReadOnlyPart *>(newPart) ); + if (view == 0L) { + kdDebug(1202) << k_funcinfo << "No view associated with this part" << endl; + return; + } + if (view->frame()->parentContainer() == 0L) return; + if (!m_bLoadingProfile) { + view->frame()->statusbar()->updateActiveStatus(); + view->frame()->parentContainer()->setActiveChild( view->frame() ); + } + //kdDebug(1202) << "KonqViewManager::slotActivePartChanged done" << endl; +} + +void KonqViewManager::emitActivePartChanged() +{ + // prevent unnecessary multiple calls to slotPartActivated: + m_activePartChangedTimer->stop(); + m_pMainWindow->slotPartActivated( activePart() ); +} + + +QSize KonqViewManager::readConfigSize( KConfig &cfg, QWidget *widget ) +{ + bool ok; + + QString widthStr = cfg.readEntry( "Width" ); + QString heightStr = cfg.readEntry( "Height" ); + + int width = -1; + int height = -1; + + QRect geom = KGlobalSettings::desktopGeometry(widget); + + if ( widthStr.contains( '%' ) == 1 ) + { + widthStr.truncate( widthStr.length() - 1 ); + int relativeWidth = widthStr.toInt( &ok ); + if ( ok ) { + width = relativeWidth * geom.width() / 100; + } + } + else + { + width = widthStr.toInt( &ok ); + if ( !ok ) + width = -1; + } + + if ( heightStr.contains( '%' ) == 1 ) + { + heightStr.truncate( heightStr.length() - 1 ); + int relativeHeight = heightStr.toInt( &ok ); + if ( ok ) { + height = relativeHeight * geom.height() / 100; + } + } + else + { + height = heightStr.toInt( &ok ); + if ( !ok ) + height = -1; + } + + return QSize( width, height ); +} + +void KonqViewManager::loadItem( KConfig &cfg, KonqFrameContainerBase *parent, + const QString &name, const KURL & defaultURL, bool openURL, bool openAfterCurrentPage ) +{ + QString prefix; + if( name != "InitialView" ) + prefix = name + '_'; + + //kdDebug(1202) << "KonqViewManager::loadItem: begin name " << name << " openURL " << openURL << endl; + + if( name.startsWith("View") || name == "empty" ) { + //load view config + QString serviceType; + QString serviceName; + if ( name == "empty" ) { + // An empty profile is an empty KHTML part. Makes all KHTML actions available, avoids crashes, + // makes it easy to DND a URL onto it, and makes it fast to load a website from there. + serviceType = "text/html"; + serviceName = "html"; + } else { + serviceType = cfg.readEntry( QString::fromLatin1( "ServiceType" ).prepend( prefix ), "inode/directory"); + serviceName = cfg.readEntry( QString::fromLatin1( "ServiceName" ).prepend( prefix ) ); + } + //kdDebug(1202) << "KonqViewManager::loadItem: ServiceType " << serviceType << " " << serviceName << endl; + + KService::Ptr service; + KTrader::OfferList partServiceOffers, appServiceOffers; + + KonqViewFactory viewFactory = KonqFactory::createView( serviceType, serviceName, &service, &partServiceOffers, &appServiceOffers, true /*forceAutoEmbed*/ ); + if ( viewFactory.isNull() ) + { + kdWarning(1202) << "Profile Loading Error: View creation failed" << endl; + return; //ugh.. + } + + bool passiveMode = cfg.readBoolEntry( QString::fromLatin1( "PassiveMode" ).prepend( prefix ), false ); + + //kdDebug(1202) << "KonqViewManager::loadItem: Creating View Stuff" << endl; + KonqView *childView = setupView( parent, viewFactory, service, partServiceOffers, appServiceOffers, serviceType, passiveMode, openAfterCurrentPage ); + + if (!childView->isFollowActive()) childView->setLinkedView( cfg.readBoolEntry( QString::fromLatin1( "LinkedView" ).prepend( prefix ), false ) ); + childView->setToggleView( cfg.readBoolEntry( QString::fromLatin1( "ToggleView" ).prepend( prefix ), false ) ); + if( !cfg.readBoolEntry( QString::fromLatin1( "ShowStatusBar" ).prepend( prefix ), true ) ) + childView->frame()->statusbar()->hide(); + + if (cfg.readBoolEntry( QString::fromLatin1( "docContainer" ).prepend( prefix ), false )) + m_pDocContainer = childView->frame(); + + if (!m_pDocContainer) + { + if (parent->frameType() == "MainWindow") + m_pDocContainer = childView->frame(); // Child view of mainWindow + + else if (parent->frameType() == "Container") + { + KonqFrameContainer* parentContainer = static_cast<KonqFrameContainer*>(parent); + KonqFrameBase* otherFrame = parentContainer->otherChild( childView->frame() ); + if (otherFrame) + { + if (childView->isPassiveMode()) + { + if (otherFrame->frameType() == "View") + { + KonqFrame* viewFrame = static_cast<KonqFrame*>(otherFrame); + if (viewFrame->childView()->isPassiveMode()) + m_pDocContainer = parentContainer; // Both views are passive, shouldn't happen + else + m_pDocContainer = viewFrame; // This one is passive, the other is active + } + } + else + { + if (otherFrame->frameType() == "View") + { + KonqFrame* viewFrame = static_cast<KonqFrame*>(otherFrame); + if (viewFrame->childView()->isPassiveMode()) + m_pDocContainer = childView->frame(); // This one is active, the other is passive + else + m_pDocContainer = parentContainer; // Both views are active + } + else + m_pDocContainer = parentContainer; // This one is active, the other is a Container + } + } + } + } + KonqConfigEvent ev( &cfg, prefix+"_", false/*load*/); + QApplication::sendEvent( childView->part(), &ev ); + + childView->frame()->show(); + + QString key = QString::fromLatin1( "URL" ).prepend( prefix ); + if ( openURL ) + { + KURL url; + + //kdDebug(1202) << "KonqViewManager::loadItem: key " << key << endl; + if ( cfg.hasKey( key ) ) + { + QString u = cfg.readPathEntry( key ); + if ( u.isEmpty() ) + u = QString::fromLatin1("about:blank"); + url = u; + } + else if(key == "empty_URL") + url = QString::fromLatin1("about:blank"); + else + url = defaultURL; + + if ( !url.isEmpty() ) + { + //kdDebug(1202) << "KonqViewManager::loadItem: calling openURL " << url.prettyURL() << endl; + //childView->openURL( url, url.prettyURL() ); + // We need view-follows-view (for the dirtree, for instance) + KonqOpenURLRequest req; + if (url.protocol() != "about") + req.typedURL = url.prettyURL(); + m_pMainWindow->openView( serviceType, url, childView, req ); + } + //else kdDebug(1202) << "KonqViewManager::loadItem: url is empty" << endl; + } + // Do this after opening the URL, so that it's actually possible to open it :) + childView->setLockedLocation( cfg.readBoolEntry( QString::fromLatin1( "LockedLocation" ).prepend( prefix ), false ) ); + } + else if( name.startsWith("Container") ) { + //kdDebug(1202) << "KonqViewManager::loadItem Item is Container" << endl; + + //load container config + QString ostr = cfg.readEntry( QString::fromLatin1( "Orientation" ).prepend( prefix ) ); + //kdDebug(1202) << "Orientation: " << ostr << endl; + Qt::Orientation o; + if( ostr == "Vertical" ) + o = Qt::Vertical; + else if( ostr == "Horizontal" ) + o = Qt::Horizontal; + else { + kdWarning() << "Profile Loading Error: No orientation specified in " << name << endl; + o = Qt::Horizontal; + } + + QValueList<int> sizes = + cfg.readIntListEntry( QString::fromLatin1( "SplitterSizes" ).prepend( prefix )); + + int index = cfg.readNumEntry( QString::fromLatin1( "activeChildIndex" ).prepend(prefix), -1 ); + + QStrList childList; + if( cfg.readListEntry( QString::fromLatin1( "Children" ).prepend( prefix ), childList ) < 2 ) + { + kdWarning() << "Profile Loading Error: Less than two children in " << name << endl; + // fallback to defaults + loadItem( cfg, parent, "InitialView", defaultURL, openURL ); + } + else + { + KonqFrameContainer *newContainer = new KonqFrameContainer( o, parent->widget(), parent ); + connect(newContainer,SIGNAL(ctrlTabPressed()),m_pMainWindow,SLOT(slotCtrlTabPressed())); + + int tabindex = -1; + if(openAfterCurrentPage && parent->frameType() == "Tabs") // Need to honor it, if possible + tabindex = static_cast<KonqFrameTabs*>(parent)->currentPageIndex() + 1; + parent->insertChildFrame( newContainer, tabindex ); + + + if (cfg.readBoolEntry( QString::fromLatin1( "docContainer" ).prepend( prefix ), false )) + m_pDocContainer = newContainer; + + loadItem( cfg, newContainer, childList.at(0), defaultURL, openURL ); + loadItem( cfg, newContainer, childList.at(1), defaultURL, openURL ); + + newContainer->setSizes( sizes ); + + if (index == 1) + newContainer->setActiveChild( newContainer->secondChild() ); + else if (index == 0) + newContainer->setActiveChild( newContainer->firstChild() ); + + newContainer->show(); + } + } + else if( name.startsWith("Tabs") ) + { + //kdDebug(1202) << "KonqViewManager::loadItem: Item is a Tabs" << endl; + + KonqFrameTabs *newContainer = new KonqFrameTabs( parent->widget(), parent, this ); + connect(newContainer,SIGNAL(ctrlTabPressed()),m_pMainWindow,SLOT(slotCtrlTabPressed())); + + parent->insertChildFrame( newContainer ); + m_pDocContainer = newContainer; + + int index = cfg.readNumEntry( QString::fromLatin1( "activeChildIndex" ).prepend(prefix), 0 ); + + QStringList childList = cfg.readListEntry( QString::fromLatin1( "Children" ).prepend( prefix ) ); + for ( QStringList::Iterator it = childList.begin(); it != childList.end(); ++it ) + { + loadItem( cfg, newContainer, *it, defaultURL, openURL ); + QWidget* currentPage = newContainer->currentPage(); + if (currentPage != 0L) { + KonqView* activeChildView = dynamic_cast<KonqFrameBase*>(currentPage)->activeChildView(); + if (activeChildView != 0L) { + activeChildView->setCaption( activeChildView->caption() ); + activeChildView->setTabIcon( activeChildView->url() ); + } + } + } + + newContainer->setActiveChild( dynamic_cast<KonqFrameBase*>(newContainer->page(index)) ); + newContainer->setCurrentPage( index ); + + newContainer->show(); + } + else + kdWarning() << "Profile Loading Error: Unknown item " << name; + + //kdDebug(1202) << "KonqViewManager::loadItem: end" << name << endl; +} + +void KonqViewManager::setProfiles( KActionMenu *profiles ) +{ + m_pamProfiles = profiles; + + if ( m_pamProfiles ) + { + connect( m_pamProfiles->popupMenu(), SIGNAL( activated( int ) ), + this, SLOT( slotProfileActivated( int ) ) ); + connect( m_pamProfiles->popupMenu(), SIGNAL( aboutToShow() ), + this, SLOT( slotProfileListAboutToShow() ) ); + } + //KonqMainWindow::enableAllActions will call it anyway + //profileListDirty(); +} + +void KonqViewManager::showProfileDlg( const QString & preselectProfile ) +{ + KonqProfileDlg dlg( this, preselectProfile, m_pMainWindow ); + dlg.exec(); + profileListDirty(); +} + +void KonqViewManager::slotProfileDlg() +{ + showProfileDlg( QString::null ); +} + +void KonqViewManager::profileListDirty( bool broadcast ) +{ + //kdDebug(1202) << "KonqViewManager::profileListDirty()" << endl; + if ( !broadcast ) + { + m_bProfileListDirty = true; +#if 0 + // There's always one profile at least, now... + QStringList profiles = KonqFactory::instance()->dirs()->findAllResources( "data", "konqueror/profiles/*", false, true ); + if ( m_pamProfiles ) + m_pamProfiles->setEnabled( profiles.count() > 0 ); +#endif + return; + } + + kapp->dcopClient()->send( "konqueror*", "KonquerorIface", "updateProfileList()", QByteArray() ); +} + +void KonqViewManager::slotProfileActivated( int id ) +{ + + QMap<QString, QString>::ConstIterator iter = m_mapProfileNames.begin(); + QMap<QString, QString>::ConstIterator end = m_mapProfileNames.end(); + + for(int i=0; iter != end; ++iter, ++i) { + if( i == id ) { + KURL u; + u.setPath( *iter ); + loadViewProfile( *iter, u.fileName() ); + break; + } + } +} + +void KonqViewManager::slotProfileListAboutToShow() +{ + if ( !m_pamProfiles || !m_bProfileListDirty ) + return; + + QPopupMenu *popup = m_pamProfiles->popupMenu(); + popup->clear(); + + // Fetch profiles + m_mapProfileNames = KonqProfileDlg::readAllProfiles(); + + // Generate accelerators + QStringList accel_strings; + KAccelGen::generateFromKeys(m_mapProfileNames, accel_strings); + + // Store menu items + QValueListIterator<QString> iter = accel_strings.begin(); + for( int id = 0; + iter != accel_strings.end(); + ++iter, ++id ) { + popup->insertItem( *iter, id ); + } + + m_bProfileListDirty = false; +} + +void KonqViewManager::setLoading( KonqView *view, bool loading ) +{ + KonqFrameContainerBase* parentContainer = view->frame()->parentContainer(); + if ( parentContainer->frameType() == "Tabs" ) { + QColor color; + KonqFrameTabs* konqframetabs = static_cast<KonqFrameTabs*>( parentContainer ); + if ( loading ) + color = QColor( (KGlobalSettings::linkColor().red() + KGlobalSettings::inactiveTextColor().red())/2, + (KGlobalSettings::linkColor().green()+ KGlobalSettings::inactiveTextColor().green())/2, + (KGlobalSettings::linkColor().blue() + KGlobalSettings::inactiveTextColor().blue())/2 ); + else + { + if ( konqframetabs->currentPage() != view->frame() ) + color = KGlobalSettings::linkColor(); + else + color = KGlobalSettings::textColor(); + } + konqframetabs->setTabColor( view->frame(), color ); + } +} + +void KonqViewManager::showHTML(bool b) +{ + if (m_pDocContainer == 0L) return; + if (m_pDocContainer->frameType() != "Tabs") return; + + KonqFrameTabs* tabContainer = static_cast<KonqFrameTabs*>(m_pDocContainer); + + QPtrList<KonqFrameBase> frameList = *tabContainer->childFrameList(); + QPtrListIterator<KonqFrameBase> it( frameList ); + + for ( it.toFirst(); it != 0L; ++it ) + { + if ( it.current()->activeChildView() && it.current()->activeChildView() !=m_pMainWindow->currentView()) + { + it.current()->activeChildView()->setAllowHTML( b ); + if( !it.current()->activeChildView()->locationBarURL().isEmpty()) + { + + m_pMainWindow->showHTML( it.current()->activeChildView(), b, false ); + } + } + } +} + + + +///////////////// Debug stuff //////////////// + +#ifndef NDEBUG +void KonqViewManager::printSizeInfo( KonqFrameBase* frame, + KonqFrameContainerBase* parent, + const char* msg ) +{ + QRect r; + r = frame->widget()->geometry(); + qDebug("Child size %s : x: %d, y: %d, w: %d, h: %d", msg, r.x(),r.y(),r.width(),r.height() ); + + if ( parent->frameType() == "Container" ) + { + QValueList<int> sizes; + sizes = static_cast<KonqFrameContainer*>(parent)->sizes(); + printf( "Parent sizes %s :", msg ); + QValueList<int>::ConstIterator it; + for( it = sizes.begin(); it != sizes.end(); ++it ) + printf( " %d", (*it) ); + printf("\n"); + } +} + +void KonqViewManager::printFullHierarchy( KonqFrameContainerBase * container ) +{ + kdDebug(1202) << "currentView=" << m_pMainWindow->currentView() << endl; + kdDebug(1202) << "docContainer=" << m_pDocContainer << endl; + + if (container) container->printFrameInfo(QString::null); + else m_pMainWindow->printFrameInfo(QString::null); +} +#endif + +#include "konq_viewmgr.moc" diff --git a/konqueror/konq_viewmgr.h b/konqueror/konq_viewmgr.h new file mode 100644 index 000000000..dff2a033c --- /dev/null +++ b/konqueror/konq_viewmgr.h @@ -0,0 +1,367 @@ +/* This file is part of the KDE project + Copyright (C) 1999 Simon Hausmann <[email protected]> + + 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_viewmgr_h__ +#define __konq_viewmgr_h__ + +#include "konq_factory.h" + +#include <qnamespace.h> +#include <qobject.h> +#include <qmap.h> +#include <qguardedptr.h> + +#include <ktrader.h> + +#include <kparts/partmanager.h> +#include "konq_openurlrequest.h" + +class QString; +class QStringList; +class QTimer; +class KConfig; +class KonqMainWindow; +class KonqFrameBase; +class KonqFrameContainer; +class KonqFrameContainerBase; +class KonqFrameTabs; +class KonqView; +class BrowserView; +class KActionMenu; + +namespace KParts +{ + class ReadOnlyPart; +} + +class KonqViewManager : public KParts::PartManager +{ + Q_OBJECT +public: + KonqViewManager( KonqMainWindow *mainWindow ); + ~KonqViewManager(); + + KonqView* Initialize( const QString &serviceType, const QString &serviceName ); + + /** + * Splits the view, depending on orientation, either horizontally or + * vertically. The first of the resulting views will contain the initial + * view, the other will be a new one, constructed from the given + * Service Type. + * If no Service Type was provided it takes the one from the current view. + * Returns the newly created view or 0L if the view couldn't be created. + * + * @param newOneFirst if true, move the new view as the first one (left or top) + */ + KonqView* splitView( Qt::Orientation orientation, + const QString & serviceType = QString::null, + const QString & serviceName = QString::null, + bool newOneFirst = false, bool forceAutoEmbed = false ); + + /** + * Does basically the same as splitView() but inserts the new view at the top + * of the view tree. + * Returns the newly created view or 0L if the view couldn't be created. + * + * @param newOneFirst if true, move the new view as the first one (left or top) + */ + KonqView* splitWindow( Qt::Orientation orientation, + const QString & serviceType = QString::null, + const QString & serviceName = QString::null, + bool newOneFirst = false); + + /** + * Converts a Container or View docContainer into a Tabs + */ + void convertDocContainer(); + + + /** + * Adds a tab to m_pMainContainer + */ + KonqView* addTab(const QString &serviceType = QString::null, + const QString &serviceName = QString::null, + bool passiveMode = false, bool openAfterCurrentPage = false ); + + + + /** + * Duplicates the specified tab, or else the current one if none is specified + */ + void duplicateTab( KonqFrameBase* tab = 0L, bool openAfterCurrentPage = false ); + + /** + * creates a new tab from a history entry + * used for MMB on back/forward + */ + KonqView* addTabFromHistory( int steps, bool openAfterCurrentPage ); + + /** + * Break the current tab off into a new window, + * if none is specified, the current one is used + */ + void breakOffTab( KonqFrameBase* tab = 0L ); + + /** + * Guess!:-) + * Also takes care of setting another view as active if @p view was the active view + */ + void removeView( KonqView *view ); + + /** + * Removes specified tab, if none is specified it remvoe the current tab + * Also takes care of setting another view as active if the active view was in this tab + */ + void removeTab( KonqFrameBase* tab = 0L ); + + /** + * Removes all, but the specified tab. If no tab is specified every tab, but the current will be removed + * Also takes care of setting the specified tab as active if the active view was not in this tab + */ + void removeOtherTabs( KonqFrameBase* tab = 0L ); + + /** + * Locates and activates the next tab + * + */ + void activateNextTab(); + + /** + * Locates and activates the previous tab + * + */ + void activatePrevTab(); + + /** + * Activate given tab + * + */ + void activateTab(int position); + + void moveTabBackward(); + void moveTabForward(); + + void reloadAllTabs(); + + /** + * Brings the tab specified by @p view to the front of the stack + * + */ + void showTab( KonqView *view ); + + /** + * Updates favicon pixmaps used in tabs + * + */ + void updatePixmaps(); + + /** + * Saves the current view layout to a config file. + * Remove config file before saving, especially if saveURLs is false. + * @param cfg the config file + * @param saveURLs whether to save the URLs in the profile + * @param saveWindowSize whether to save the size of the window in the profile + */ + void saveViewProfile( KConfig & cfg, bool saveURLs, bool saveWindowSize ); + + /** + * Saves the current view layout to a config file. + * Remove config file before saving, especially if saveURLs is false. + * @param fileName the name of the config file + * @param profileName the name of the profile + * @param saveURLs whether to save the URLs in the profile + * @param saveWindowSize whether to save the size of the window in the profile + */ + void saveViewProfile( const QString & fileName, const QString & profileName, + bool saveURLs, bool saveWindowSize ); + + /** + * Loads a view layout from a config file. Removes all views before loading. + * @param cfg the config file + * @param filename if set, remember the file name of the profile (for save settings) + * It has to be under the profiles dir. Otherwise, set to QString::null + * @param forcedURL if set, the URL to open, whatever the profile says + * @param req attributes related to @p forcedURL + * @param resetWindow if the profile doesn't have attributes like size or toolbar + * settings, they will be reset to the defaults + */ + void loadViewProfile( KConfig &cfg, const QString & filename, + const KURL & forcedURL = KURL(), + const KonqOpenURLRequest &req = KonqOpenURLRequest(), + bool resetWindow = false, bool openURL = true ); + + /** + * Loads a view layout from a config file. Removes all views before loading. + * @param path the full path to the config file + * @param filename if set, remember the file name of the profile (for save settings) + * It has to be under the profiles dir. Otherwise, set to QString::null + * @param forcedURL if set, the URL to open, whatever the profile says + * @param req attributes related to @p forcedURL + * @param resetWindow if the profile doesn't have attributes like size or toolbar + * settings, they will be reset to the defaults + */ + void loadViewProfile( const QString & path, const QString & filename, + const KURL & forcedURL = KURL(), + const KonqOpenURLRequest &req = KonqOpenURLRequest(), + bool resetWindow = false, bool openURL = true ); + /** + * Return the filename of the last profile that was loaded + * by the view manager. For "save settings". + */ + QString currentProfile() const { return m_currentProfile; } + /** + * Return the name (i18n'ed) of the last profile that was loaded + * by the view manager. For "save settings". + */ + QString currentProfileText() const { return m_currentProfileText; } + + /** + * Whether we are currently loading a profile + */ + bool isLoadingProfile() const { return m_bLoadingProfile; } + + void clear(); + + KonqView *chooseNextView( KonqView *view ); + + /** + * Called whenever + * - the total number of views changed + * - the number of views in passive mode changed + * The implementation takes care of showing or hiding the statusbar indicators + */ + void viewCountChanged(); + + void setProfiles( KActionMenu *profiles ); + + void profileListDirty( bool broadcast = true ); + + KonqFrameBase *docContainer() const { return m_pDocContainer; } + void setDocContainer( KonqFrameBase* docContainer ) { m_pDocContainer = docContainer; } + + KonqMainWindow *mainWindow() const { return m_pMainWindow; } + + /** + * Reimplemented from PartManager + */ + virtual void removePart( KParts::Part * part ); + + /** + * Reimplemented from PartManager + */ + virtual void setActivePart( KParts::Part *part, QWidget *widget = 0L ); + + void setActivePart( KParts::Part *part, bool immediate ); + + void showProfileDlg( const QString & preselectProfile ); + + /** + * The widget is the one which you are referring to. + */ + static QSize readConfigSize( KConfig &cfg, QWidget *widget = NULL); + +#ifndef NDEBUG + void printFullHierarchy( KonqFrameContainerBase * container ); +#endif + + void setLoading( KonqView *view, bool loading ); + + void showHTML(bool b); + + QString profileHomeURL() const { return m_profileHomeURL; } + +protected slots: + void emitActivePartChanged(); + + void slotProfileDlg(); + + void slotProfileActivated( int id ); + + void slotProfileListAboutToShow(); + + void slotPassiveModePartDeleted(); + + void slotActivePartChanged ( KParts::Part *newPart ); + +protected: + + /** + * Load the config entries for a view. + * @param cfg the config file + * ... + * @param defaultURL the URL to use if the profile doesn't contain urls + * @param openURL whether to open urls at all (from the profile or using @p defaultURL). + * (this is set to false when we have a forcedURL to open) + */ + void loadItem( KConfig &cfg, KonqFrameContainerBase *parent, + const QString &name, const KURL & defaultURL, bool openURL, bool openAfterCurrentPage = false ); + + // Disabled - we do it ourselves + virtual void setActiveInstance( KInstance * ) {} + +private: + + /** + * Creates a new View based on the given ServiceType. If serviceType is empty + * it clones the current view. + * Returns the newly created view. + */ + KonqViewFactory createView( const QString &serviceType, + const QString &serviceName, + KService::Ptr &service, + KTrader::OfferList &partServiceOffers, + KTrader::OfferList &appServiceOffers, + bool forceAutoEmbed = false ); + + /** + * Mainly creates the backend structure(KonqView) for a view and + * connects it + */ + KonqView *setupView( KonqFrameContainerBase *parentContainer, + KonqViewFactory &viewFactory, + const KService::Ptr &service, + const KTrader::OfferList &partServiceOffers, + const KTrader::OfferList &appServiceOffers, + const QString &serviceType, + bool passiveMode, bool openAfterCurrentPage = false); + +#ifndef NDEBUG + //just for debugging + void printSizeInfo( KonqFrameBase* frame, + KonqFrameContainerBase* parent, + const char* msg ); +#endif + + KonqMainWindow *m_pMainWindow; + + KonqFrameBase *m_pDocContainer; + + QGuardedPtr<KActionMenu> m_pamProfiles; + bool m_bProfileListDirty; + bool m_bLoadingProfile; + QString m_currentProfile; + QString m_currentProfileText; + QString m_profileHomeURL; + + QMap<QString, QString> m_mapProfileNames; + + QTimer *m_activePartChangedTimer; +}; + +#endif diff --git a/konqueror/konqbrowser.desktop b/konqueror/konqbrowser.desktop new file mode 100644 index 000000000..81859c4e1 --- /dev/null +++ b/konqueror/konqbrowser.desktop @@ -0,0 +1,98 @@ +[Desktop Entry] +Type=Application +Exec=kfmclient openProfile webbrowsing +Icon=konqueror +DocPath=konqueror/index.html + +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]=คอนเควอร์เรอร์ +GenericName=Web Browser +GenericName[af]=Web Blaaier +GenericName[ar]=متصفح الشبكة +GenericName[az]=Veb Səyyahı +GenericName[be]=Вандроўнік па Сеціве +GenericName[bg]=Уеб браузър +GenericName[bn]=ওয়েব ব্রাউজার +GenericName[br]=Furcher ar Gwiad +GenericName[bs]=WWW Preglednik +GenericName[ca]=Fullejador web +GenericName[cs]=WWW prohlížeč +GenericName[csb]=Przezérnik WWW +GenericName[cy]=Porydd Gwe +GenericName[da]=Browser +GenericName[de]=Webbrowser +GenericName[el]=Περιηγητής ιστού +GenericName[eo]=TTT-legilo +GenericName[es]=Navegador web +GenericName[et]=Veebilehitseja +GenericName[eu]=Web arakatzailea +GenericName[fa]=مرورگر وب +GenericName[fi]=WWW-selain +GenericName[fo]=Alnótsfar +GenericName[fr]=Navigateur web +GenericName[fy]=Webblêder +GenericName[ga]=Brabhsálaí Lín +GenericName[gl]=Navegador Web +GenericName[he]=דפדפן אינטרנט +GenericName[hi]=वेब ब्राउज़र +GenericName[hr]=Web preglednik +GenericName[hu]=Webböngésző +GenericName[id]=Peselancar Web +GenericName[is]=Vafri +GenericName[it]=Browser Web +GenericName[ja]=ウェブブラウザ +GenericName[ka]=ვებ–ბრაუზერი +GenericName[kk]=Веб браузер +GenericName[km]=កម្មវិធីរុករកបណ្ដាញ +GenericName[ko]=웹 브라우저 +GenericName[lo]=ເວັບບຣາວເຊີ +GenericName[lt]=Žiniatinklio naršyklė +GenericName[lv]=Tīmekļa Pārlūks +GenericName[mk]=Прелистувач на Интернет +GenericName[mn]=Веб-Хөтөч +GenericName[ms]=Pelayar Web +GenericName[nb]=Nettleser +GenericName[nds]=Nettkieker +GenericName[ne]=वेब ब्राउजर +GenericName[nl]=Webbrowser +GenericName[nn]=Nettlesar +GenericName[nso]=Seinyakisi sa Web +GenericName[pa]=ਵੈਬ ਝਲਕਾਰਾ +GenericName[pl]=Przeglądarka WWW +GenericName[pt]=Navegador Web +GenericName[pt_BR]=Navegador Web +GenericName[ro]=Navigator de web +GenericName[ru]=Веб-браузер +GenericName[rw]=Mucukumbuzi Urubuga +GenericName[se]=Fierpmádatlogan +GenericName[sk]=Webový prehliadač +GenericName[sl]=Spletni brskalnik +GenericName[sr]=Веб прегледач +GenericName[sr@Latn]=Veb pregledač +GenericName[ss]=Ibrawuza yeWeb +GenericName[sv]=Webbläsare +GenericName[ta]=வலை உலாவி +GenericName[te]=వెబ్ బ్రౌజర్ +GenericName[tg]=Тафсиргари вэб +GenericName[th]=เว็บบราวเซอร์ +GenericName[tr]=Web Tarayıcı +GenericName[uk]=Навігатор Тенет +GenericName[uz]=Veb-brauzer +GenericName[uz@cyrillic]=Веб-браузер +GenericName[ven]=Buronza ya Webu +GenericName[vi]=Trình duyệt mạng +GenericName[wa]=Betchteu waibe +GenericName[xh]=Umkhangeli zincwadi we Web +GenericName[zh_CN]=Web 浏览器 +GenericName[zh_TW]=網頁瀏覽器 +GenericName[zu]=Umcingi we-Web +Categories=Qt;KDE;Network; diff --git a/konqueror/konqfilemgr.desktop b/konqueror/konqfilemgr.desktop new file mode 100644 index 000000000..3b10dc9e0 --- /dev/null +++ b/konqueror/konqfilemgr.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Type=Application +Exec=kfmclient openProfile filemanagement +Icon=kfm +DocPath=konqueror/index.html + +Name=File Manager +Name[af]=Lêer Bestuurder +Name[ar]=مدبّر الملفات +Name[az]=Fayl İdarəcisi +Name[be]=Кіраўнік файлаў +Name[bg]=Файлов браузър +Name[bn]=ফাইল ম্যানেজার +Name[br]=Merour restroù +Name[bs]=Upravitelj datotekama +Name[ca]=Gestor de fitxers +Name[cs]=Správce souborů +Name[csb]=Menedżer lopków +Name[cy]=Rheolydd Ffeiliau +Name[da]=Filhåndtering +Name[de]=Dateimanager +Name[el]=Διαχειριστής αρχείων +Name[eo]=Dosieradministrilo +Name[es]=Gestor de archivos +Name[et]=Failihaldur +Name[eu]=Fitxategi kudeatzailea +Name[fa]=مدیر پرونده +Name[fi]=Tiedostonhallinta +Name[fo]=Fíluhandfarari +Name[fr]=Gestionnaire de fichiers +Name[fy]=Triembehearder +Name[ga]=Bainisteoir Comhad +Name[gl]=Xestor de Ficheiros +Name[he]=מנהל הקבצים +Name[hi]=फ़ाइल प्रबंधक +Name[hr]=Upravitelj datotekama +Name[hsb]=Datajowy manager +Name[hu]=Fájlkezelő +Name[id]=Manajer File +Name[is]=Skráastjóri +Name[it]=File manager +Name[ja]=ファイルマネージャ +Name[ka]=ფაილთა მენჯერი +Name[kk]=Файл менеджері +Name[km]=កម្មវិធីគ្រប់គ្រងឯកសារ +Name[ko]=파일 관리자 +Name[lo]=ເຄື່ອງມືການຈັດການແຟ້ມ +Name[lt]=Bylų tvarkyklė +Name[lv]=Failu Menedžeris +Name[mk]=Менаџер на датотеки +Name[mn]=Файл удирдагч +Name[ms]=Pengurus Fail +Name[mt]=Manager tal-Fajls +Name[nb]=Filbehandler +Name[nds]=Dateipleger +Name[ne]=फाइल प्रबन्धक +Name[nl]=Bestandsbeheerder +Name[nn]=Filhandsamar +Name[nso]=Molaodi wa Faele +Name[oc]=Gestionari de fiquièrs +Name[pa]=ਫਾਇਲ ਮੈਨੇਜਰ +Name[pl]=Menedżer plików +Name[pt]=Gestor de Ficheiros +Name[pt_BR]=Gerenciador de Arquivos +Name[ro]=Manager de fișiere +Name[ru]=Файловый менеджер +Name[rw]= Mucungamadosiye +Name[se]=Fiilagieđahalli +Name[sk]=Správca súborov +Name[sl]=Upravitelj datotek +Name[sr]=Менаџер фајлова +Name[sr@Latn]=Menadžer fajlova +Name[ss]=Siphatsi selifayela +Name[sv]=Filhanterare +Name[ta]=கோப்பு மேலாளர் +Name[te]=దస్త్రాల అభికర్త +Name[tg]=Мудири файл +Name[th]=เครื่องมือจัดการแฟ้ม +Name[tr]=Dosya Yöneticisi +Name[tt]=Birem İdäräçe +Name[uk]=Менеджер файлів +Name[uz]=Fayl boshqaruvchisi +Name[uz@cyrillic]=Файл бошқарувчиси +Name[ven]=Mulanguli wa faela +Name[vi]=Trình quản lí tập tin +Name[wa]=Manaedjeu di fitchîs +Name[xh]=Umphathi Wefayile +Name[zh_CN]=文件管理器 +Name[zh_TW]=檔案管理程式 +Name[zu]=imenenja yamafayela diff --git a/konqueror/konqueror.desktop b/konqueror/konqueror.desktop new file mode 100644 index 000000000..e75dfae29 --- /dev/null +++ b/konqueror/konqueror.desktop @@ -0,0 +1,100 @@ +[Desktop Entry] +Type=Application +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]=คอนเควอร์เรอร์ +Exec=konqueror %U +Comment=KDE File Manager & Web Browser +Comment[af]=Kde Lêer Bestuurder & Web Blaaier +Comment[ar]=مدبِر KDE للملفات و متصفح الشبكة +Comment[az]=KDE Fayl İdarəcisi və İnternet Səyyahı +Comment[be]=Файлавы кіраўнік і вандроўнік па Сеціве для KDE +Comment[bg]=Файлов и уеб браузър +Comment[bn]=কে.ডি.ই ফাইল ম্যানেজার এবং ওয়েব ব্রাউজার +Comment[br]=Merour restroù ha merdeer gwiad KDE +Comment[bs]=KDE upravitelj datotekama & Web preglednik +Comment[ca]=El gestor de fitxers i fullejador Web del KDE +Comment[cs]=Správce souborů a prohlížeč Webu pro prostředí KDE +Comment[csb]=KDE Menedżer lopków ë przezérnik WWW +Comment[cy]=Trefnydd Ffeiliau a Porydd Gwe KDE +Comment[da]=KDE's filhåndtering og netsøgning +Comment[de]=Der Dateimanager und Webbrowser von KDE +Comment[el]=Διαχειριστής αρχείων & Περιηγητής ιστού του KDE +Comment[eo]=KDE-dosieradministrilo kaj TTT-legilo +Comment[es]=Gestor de archivos y navegador web de KDE +Comment[et]=KDE failihaldur & veebilehitseja +Comment[eu]=KDE fitxategi kudeatzailea eta Web arakatzailea +Comment[fa]=مدیر پرونده و مرورگر وب KDE +Comment[fi]=KDE:n tiedostonhallinta ja WWW-selain +Comment[fr]=Gestionnaire de fichiers et navigateur web de KDE +Comment[fy]=KDE's Triembehearder en webblêder +Comment[ga]=Bainisteoir Comhad & Brabhsálaí KDE +Comment[gl]=Xestor de Ficheiros e Navegador Web de KDE +Comment[he]=מנהל הקבצים ודפדפן האינטרנט של KDE +Comment[hi]=केडीई फ़ाइल प्रबंधक व वेब ब्राउज़र +Comment[hr]=KDE upravitelj datotekama i web preglednik +Comment[hu]=KDE fájlkezelő és webböngésző +Comment[id]=Manajer File KDE & browser web +Comment[is]=KDE skráastjóri og vafri +Comment[it]=Il file manager e browser Web di KDE +Comment[ja]=KDE ファイルマネージャ & ウェブブラウザ +Comment[ka]=ფაილური მენეჯერი და ვებ ბრაუზერი +Comment[kk]=KDE файл менеджері және Веб браузері +Comment[km]=កម្មវិធីគ្រប់គ្រងឯកសារ & កម្មវិធីរុករកបណ្ដាញរបស់ KDE +Comment[ko]=KDE 파일 관리자와 웹 브라우저 +Comment[lo]=ຕົວຈັດການແຟ້ມແລະເວ໊ບບາວເຊີ KDE +Comment[lt]=KDE bylų tvarkyklė ir žiniatinklio naršyklė +Comment[lv]=KDE Failu Menedžeris un Web Pārlūks +Comment[mk]=Менаџер на датотеки и веб-прелистувач во KDE +Comment[mn]=КДЭ-н Файл удирдагч ба Вэб-Хөтөч +Comment[ms]=Pengurus Fail KDE & Pelayar Web +Comment[mt]=Manager tal-fajls u Web Browser tal-KDE +Comment[nb]=Filbehandler og nettleser for KDE +Comment[nds]=KDE sien Dateipleger un Nettkieker +Comment[ne]=KDE फाइल प्रबन्धक र वेब ब्राउजर +Comment[nl]=KDE's bestandsbeheerder en webbrowser +Comment[nn]=Filhandsamar og nettlesar for KDE +Comment[nso]=Seinyakisi sa Web & Molaodi wa Faele ya KDE +Comment[oc]=Lo gestionari de fiquièrs e navigador Web KDE +Comment[pa]=KDE ਫਾਇਲ ਮੈਨੇਜਰ ਅਤੇ ਵੈੱਬ ਝਲਕਾਰਾ +Comment[pl]=KDE Menedżer plików i przeglądarka WWW +Comment[pt]=Gestor de ficheiros e navegador na WWW +Comment[pt_BR]=Gerenciador de Arquivos & Navegador Web do KDE +Comment[ro]=Manager de fișiere KDE și navigator de web +Comment[ru]=Файловый менеджер и веб-браузер +Comment[rw]=KDE Mugengadosiye & Mucukumbuzi w'Urubugamakuru +Comment[se]=KDE fiilagieđahalli ja fierpmádatlogan +Comment[sk]=KDE Správca súborov a Web prehliadač +Comment[sl]=Upravitelj datotek za KDE in spletni brskalnik +Comment[sr]=Менаџер фајлова и веб прегледач за KDE +Comment[sr@Latn]=Menadžer fajlova i veb pregledač za KDE +Comment[sv]=KDE:s filhanterare och webbläsare +Comment[ta]=KDE கோப்பு மேலாளர் மற்றும் வலை உலாவி +Comment[te]=కెడిఈ దస్త్ర అభికర్త & వెబ్ బ్రౌజర్ +Comment[tg]=Мудири файл ва мурургари шабакаи KDE +Comment[th]=เครื่องมือจัดการแฟ้มและท่องเว็บของ KDE +Comment[tr]=KDE Dosya Yöneticisi ve İnternet Tarayıcısı +Comment[tt]=KDE Birem-İdäräçe & Web-Gizgeç +Comment[uk]=Менеджер файлів KDE та навігатор Тенет +Comment[uz]=KDE uchun fayl boshqaruvchi va veb-brauzer +Comment[uz@cyrillic]=KDE учун файл бошқарувчи ва веб-браузер +Comment[ven]=Mulanguli wa faela ya KDE & Buronza ya webe +Comment[vi]=Trình quản lí Tập tin và Duyệt mạng KDE +Comment[wa]=Manaedjeu di fitchîs eyet betchteu waibe di KDE +Comment[xh]=Umphathi Wefayile ye KDE & Umkhangeli zincwadi we Web +Comment[zh_CN]=KDE 文件管理器和 Web 浏览器 +Comment[zh_TW]=KDE 檔案管理程式和網頁瀏覽器 +Comment[zu]=Imenenja yamafayela ye-KDE & Umcingi we-Web +Icon=konqueror +X-DCOP-ServiceType=multi +X-KDE-StartupNotify=true +X-KDE-HasTempFileOption=true diff --git a/konqueror/konqueror.kcfg b/konqueror/konqueror.kcfg new file mode 100644 index 000000000..a412347d1 --- /dev/null +++ b/konqueror/konqueror.kcfg @@ -0,0 +1,620 @@ +<?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" > + <include>khtmldefaults.h</include> + <kcfgfile name="konquerorrc" /> + + + <group name="FMSettings"> +<!-- behaviour.cpp --> + <entry key="AlwaysNewWin" type="Bool"> <!--LIBKONQ--> + <default>false</default> + <label>Open folders in separate windows</label> + <whatsthis>If this option is checked, Konqueror will open a new window when you open a folder, rather than showing that folder's contents in the current window.</whatsthis> + <!-- checked --> + </entry> + <entry key="HomeURL" type="Path"> <!--LIBKONQ--> + <default>~</default> + <label>Home Folder</label> + <whatsthis>This is the URL (e.g. a folder or a web page) where Konqueror will jump to when the \"Home\" button is pressed. This is usually your home folder, symbolized by a 'tilde' (~).</whatsthis> + <!-- checked --> + </entry> + <entry key="ShowFileTips" type="Bool"> <!--LIBKONQ--> + <default>true</default> + <label>Show file tips</label> + <whatsthis>Here you can control if, when moving the mouse over a file, you want to see a small popup window with additional information about that file</whatsthis> + <!-- checked --> + </entry> + <entry key="FileTipsItems" type="Int"> <!--LIBKONQ--> + <default>6</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="ShowPreviewsInFileTips" type="Bool"> <!--LIBKONQ--> + <default>true</default> + <label>Show previews in file tips</label> + <whatsthis>Here you can control if you want the popup window to contain a larger preview for the file, when moving the mouse over it</whatsthis> + <!-- checked --> + </entry> + <entry key="RenameIconDirectly" type="Bool"> <!--LIBKONQ--> + <default>false</default> + <label>Rename icons inline</label> + <whatsthis>Checking this option will allow files to be renamed by clicking directly on the icon name.</whatsthis> + <!-- checked --> + </entry> + <entry key="ShowDeleteCommand" type="Bool"> + <default>true</default> + <label>Show 'Delete' menu entries which bypass the trashcan</label> + <whatsthis>Uncheck this if you do not want 'Delete' menu commands to be displayed on the desktop and in the file manager's menus and context menus. You can still delete files when hidden by holding the Shift key while calling 'Move to Trash'.</whatsthis> + <!-- checked --> + </entry> +<!-- fontopts.cpp --> + <entry key="StandardFont" type="Font"> <!--LIBKONQ--> + <default code="true">KGlobalSettings::generalFont()</default> + <label>Standard font</label> + <whatsthis>This is the font used to display text in Konqueror windows.</whatsthis> + <!-- checked --> + </entry> + <entry key="NormalTextColor" type="Color"> <!--LIBKONQ--> + <default code="true"></default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="ItemTextBackground" type="Color"> <!--LIBKONQ--> + <default></default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="TextHeight" type="Int"> <!--LIBKONQ--> + <default>2</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="TextWidth" type="Int"> <!--LIBKONQ--> + <default>70</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="DisplayFileSizeInBytes" type="Bool"> <!--LIBKONQ--> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry name="TextPreviewIconOpacity" key="TextpreviewIconOpacity" type="Int"> <!--LIBKONQ--> + <default>70</default> + <min>0</min> + <max>255</max> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry name="FmUnderlineLinks" key="UnderlineLinks" type="Bool"> <!--LIBKONQ--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- htmlopts.cpp --> + <entry name="MmbOpensTab" key="MMBOpensTab" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="AlwaysTabbedMode" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- advancedTabDialog.cpp --> + <entry key="NewTabsInFront" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="OpenAfterCurrentPage" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="PermanentCloseButton" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="KonquerorTabforExternalURL" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="PopupsWithinTabs" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="TabCloseActivatePrevious" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- konq_settings.cc --> + <entry key="WordWrapText" type="Bool"> <!--LIBKONQ--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- no writeEntry --> + </entry> +<!-- konq_tabs.cc --> + <entry key="MouseMiddleClickClosesTab" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- no writeEntry / hidden--> + </entry> + <entry key="HoverCloseButton" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- no writeEntry / hidden--> + </entry> + <entry key="AddTabButton" type="Bool"> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="CloseTabButton" type="Bool"> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="MaximumTabLength" type="Int"> + <default>30</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="MinimumTabLength" type="Int"> + <default>3</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="TabPosition" type="String"> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + </group> + + <group name="HTML Settings" > +<!-- appearance.cpp --> + <entry key="MediumFontSize" type="Int"> <!--KHTML--> + <default>12</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="MinimumFontSize" type="Int"> <!--KHTML--> + <default code="true">HTML_DEFAULT_MIN_FONT_SIZE</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="Fonts" type="StringList"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="DefaultEncoding" type="String"> <!--KHTML--> + <default code="true">QString::null</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- htmlopts.cpp --> + <entry key="ChangeCursor" type="Bool"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry name="HtmlUnderlineLinks" key="UnderlineLinks" type="Bool"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="HoverLinks" type="Bool"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="AutoLoadImages" type="Bool"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="ShowAnimations" type="String"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="AutoDelayedActions" type="Bool"> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="FormCompletion" type="Bool"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="MaxFormCompletionItems" type="Int"> <!--KHTML--> + <default>10</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- konq_view.cc --> + <entry key="EnableFavicon" type="Bool"> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- Can't find writeEntry --> + </entry> +<!-- KDELIBS/khtml_part.cpp --> + <entry key="AutomaticDetectionLanguage" type="Int"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> +<!-- KDELIBS/khtml_settings.cpp --> + <entry key="EnforceDefaultCharset" type="Bool"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + <!-- Can't find writeEntry --> + </entry> +<!-- kcmcss.cpp KDELIBS/khtml_settings.cpp --> + <entry key="UserStyleSheetEnabled" type="Bool"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> + +<!-- Are these entries? Can't find writeEntry(..)! They belong maybe to DefaultEncoding. + + <entry name="iso8859_1" key="iso8859-1" type="StringList"> </entry> + <entry name="iso8859_10" key="iso8859-10" type="StringList"> </entry> + <entry name="iso8859_13" key="iso8859-13" type="StringList"> </entry> + <entry name="iso8859_14" key="iso8859-14" type="StringList"> </entry> + <entry name="iso8859_15" key="iso8859-15" type="StringList"> </entry> + <entry name="iso8859_2" key="iso8859-2" type="StringList"> </entry> + <entry name="iso8859_3" key="iso8859-3" type="StringList"> </entry> + <entry name="iso8859_4" key="iso8859-4" type="StringList"> </entry> + <entry name="iso8859_5" key="iso8859-5" type="StringList"> </entry> + <entry name="iso8859_6" key="iso8859-6" type="StringList"> </entry> + <entry name="iso8859_7" key="iso8859-7" type="StringList"> </entry> + <entry name="iso8859_8" key="iso8859-8" type="StringList"> </entry> + <entry name="iso8859_9" key="iso8859-9" type="StringList"> </entry> + <entry name="iso8859_r" key="koi8-r" type="StringList"> </entry> + <entry name="iso8859_u" key="koi8-u" type="StringList"> </entry> + <entry name="microsoft_cp1251" key="microsoft-cp1251" type="StringList"> </entry> + <entry name="paratype_cp154" key="paratype-cp154" type="StringList"> </entry> + --> + </group> + + <group name="MainView Settings" > +<!-- htmlopts.cpp --> + <entry key="OpenMiddleClick" type="Bool"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="BackRightClick" type="Bool"> <!--KHTML--> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- konq_mainwindow.cpp --> + <entry key="SaveViewPropertiesLocally" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry name="HtmlAllowed" key="HTMLAllowed" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry name="MainViewViewMode" key="ViewMode" type="String"> <!-- has dupes --> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- konq_guiclients.cpp --> + <entry key="ToggableViewsShown" type="StringList"> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + </group> + + <group name="HistorySettings" > +<!-- history_module.cpp --> + <entry key="OpenGroups" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + </group> + + <group name="Java/JavaScript Settings" > +<!-- javaopts.cpp --> + <entry key="ShowJavaConsole" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="UseSecurityManager" type="Bool"> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="UseKio" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="ShutdownAppletServer" type="Bool"> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="AppletServerTimeout" type="Int"> + <default>60</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="JavaPath" type="Path"> + <default code="true"> +#if defined(PATH_JAVA) +PATH_JAVA +#else +"java" +#endif + </default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="JavaDomains" type="StringList"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="JavaDomainSettings" type="StringList"> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="JavaScriptDomainAdvice" type="StringList"> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="JavaArgs" type="String"> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- jsopts.cpp --> + <entry key="ECMADomains" type="StringList"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="ECMADomainSettings" type="StringList"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="ReportJavaScriptErrors" type="Bool"> <!--KHTML--> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="EnableJavaScriptDebug" type="Bool"> <!--KHTML--> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> +<!-- jspolicies.cpp --> + <entry key="EnableJavaScript" type="Bool"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="WindowOpenPolicy" type="UInt"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="WindowResizePolicy" type="UInt"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="WindowMovePolicy" type="UInt"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="WindowFocusPolicy" type="UInt"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="WindowStatusPolicy" type="UInt"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> +<!-- pluginopts.cpp --> + <entry key="EnablePlugins" type="Bool"> <!--KHTML--> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="PluginDomains" type="StringList"> <!--KHTML--> + <label></label> + <whatsthis></whatsthis> + </entry> + </group> + + <group name="ModeToolBarServices" > +<!-- konq_mainwindow.cc --> + <entry key="konq_iconview" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="konq_listview" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="libcervisia" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="libkonqiconview" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="libkonqlistview" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + </group> + + <group name="Notification Messages" > +<!-- advancedTabDialog.cpp konq_mainwindow.cc --> + <entry key="MultipleTabConfirm" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + + <entry name="plugin_application_x_shockwave_flash" key="plugin-application/x-shockwave-flash" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry name="plugin_image_svg_xml" key="plugin-image/svg+xml" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + </group> + + <group name="Reusing" > + <entry key="SafeParts" type="StringList"> + <default>SAFE</default> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="AlwaysHavePreloaded" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="MaxPreloadCount" type="Int"> + <default>1</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="PreloadOnStartup" type="Bool"> + <label></label> + <whatsthis></whatsthis> + </entry> + </group> + + <group name="Settings" > + <entry key="BgImage" type="String"> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="SaveURLInProfile" type="Bool"> + <default>true</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="SaveWindowSizeInProfile" type="Bool"> + <default>false</default> + <label></label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry name="SettingsCompletionMode" key="CompletionMode" type="Enum"> + <default code="true">KGlobalSettings::completionMode()</default> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="Number of most visited URLs" type="Int"> + <default>10</default> + <label></label> + <whatsthis></whatsthis> + </entry> + </group> + + <group name="Trash" > +<!-- behaviour.cpp --> + <entry key="ConfirmDelete" type="Bool"> + <default>true</default> + <label>Ask confirmation for deleting a file.</label> + <whatsthis></whatsthis> + <!-- checked --> + </entry> + <entry key="ConfirmTrash" type="Bool"> + <default>true</default> + <label>Ask confirmation for move to trash</label> + <whatsthis>This option tells Konqueror whether to ask for a confirmation when you move the file to your trash folder, from where it can be recovered very easily.</whatsthis> + <!-- checked --> + </entry> + </group> + + <group name="General" > +<!-- konq_mainwindow.cpp --> + <entry key="TerminalApplication" type="String"> + <default>konsole</default> + <label></label> + <whatsthis>This option tells Konqueror whether to ask for a confirmation when you simply delete the file.</whatsthis> + <!-- checked --> + </entry> + </group> + +</kcfg> diff --git a/konqueror/konqueror.rc b/konqueror/konqueror.rc new file mode 100644 index 000000000..aba05cdc0 --- /dev/null +++ b/konqueror/konqueror.rc @@ -0,0 +1,152 @@ +<?xml version="1.0"?> +<!DOCTYPE gui SYSTEM "kpartgui.dtd"> +<gui name="Konqueror" version="59"> +<MenuBar> + <Menu name="file" noMerge="1"><text>&Location</text> + <Action name="new_window"/> + <Action name="newtab"/> + <Action name="duplicate_window"/> + <Action name="open_location"/> + <Separator/> + <Action name="sendURL"/> + <Action name="sendPage"/> + <Separator/> + <Merge/> <!--Includes termination separator--> + <Action name="print"/> + <DefineGroup name="print" /> + <Separator/> + <ActionList name="openwith" /> <!--Includes termination separator--> + <Action name="quit"/> + </Menu> + <Menu name="edit" noMerge="1"><text>&Edit</text> <!--Here is what applies to a selection--> + <Action name="undo" /> + <Action name="cut"/> + <Action name="copy"/> + <Action name="paste"/> + <Action name="rename"/> + <Action name="trash"/> + <Action name="del" /> + <ActionList name="operations" /><!-- copy files and move files, when two directory views --> + <Separator/> + <Action name="new_menu"/> + <Separator/> + <Action name="editMimeType"/> + <Action name="properties"/> + <WeakSeparator/> + <Merge/> + </Menu> + <Menu name="view" noMerge="1"><text>&View</text> <!--Here is what applies to the active view--> + <ActionList name="viewmode" /> + <Action name="usehtml"/> + <Action name="lock"/> + <Action name="link"/> + <Separator/> + <Action name="reload"/> + <Action name="stop" /> + <WeakSeparator/> + <Merge/> + </Menu> + <Menu name="go"><text>&Go</text> + <Action name="back"/> + <Action name="forward"/> + <Action name="up"/> + <Action name="home"/> + <Separator/> + <Action name="go_system"/> + <Action name="go_applications"/> + <Action name="go_network_folders"/> + <Action name="go_settings"/> + <Action name="go_media"/> + <Action name="go_dirtree"/> + <Action name="go_trash"/> + <Action name="go_autostart"/> + <Action name="go_history"/> + <Action name="go_most_often"/> + <Separator/> + <Action name="history"/> + </Menu> + <Action name="bookmarks"/> + <Menu name="tools"><text>&Tools</text> + <Action name="open_terminal"/> + <Action name="findfile"/> + <WeakSeparator/> + <Merge/> + </Menu> + <Menu name="settings" noMerge="1"><text>&Settings</text> + <Action name="options_show_menubar"/> + <Merge name="StandardToolBarMenuHandler" /> + <Separator/> + <Action name="fullscreen"/> + <Separator/> + <Action name="saveViewPropertiesLocally"/> + <Action name="removeLocalProperties"/> + <Separator/> + <Action name="loadviewprofile"/> + <Action name="saveviewprofile"/> + <Action name="saveremoveviewprofile"/> + <Separator/> + <Action name="options_configure_extensions"/> + <Action name="configurespellcheck"/> + <Action name="options_configure_keybinding"/> + <Action name="options_configure_toolbars"/> + <Action name="options_configure"/> + </Menu> + <Menu name="window" append="settings_merge"><text>&Window</text> + <Action name="splitviewh"/> + <Action name="splitviewv"/> + <Action name="removeview"/> + <Separator/> + <Action name="newtab"/> + <Action name="duplicatecurrenttab"/> + <Action name="breakoffcurrenttab"/> + <Action name="removecurrenttab"/> + <Separator/> + <Action name="tab_move_left"/> + <Action name="tab_move_right"/> + <Separator/> + <ActionList name="toggleview" /> + </Menu> + <Menu name="help" append="about_merge"><text>&Help</text> + <Action name="konqintro"/> + </Menu> + <Merge/> +</MenuBar> +<ToolBar fullWidth="true" name="mainToolBar" newline="true"><text>Main Toolbar</text> + <Action name="back"/> + <Action name="forward"/> + <Action name="up"/> + <Action name="home"/> + <Separator/> + <Action name="reload"/> + <Action name="stop"/> + <Separator/> + <Action name="print"/> + <WeakSeparator/> + <Merge/> + <Separator/> + <ActionList name="viewmode_toolbar" /> + <ActionList name="fullscreen" /> + <WeakSeparator/> + <Action name="animated_logo"/> +</ToolBar> +<ToolBar hidden="true" name="extraToolBar" newline="false" index="1"><text>Extra Toolbar</text> + <Action name="konq_sidebartng" /> + <Action name="findfile" /> + <Action name="splitviewv" /> + <Action name="splitviewh" /> + <Action name="removeview" /> +</ToolBar> +<ToolBar fullWidth="true" name="locationToolBar" newline="true"><text>Location Toolbar</text> + <Action name="clear_location" /> + <Action name="location_label" /> + <Action name="toolbar_url_combo" /> + <Action name="go_url" /> +</ToolBar> +<ToolBar noEdit="true" iconText="icontextright" fullWidth="true" name="bookmarkToolBar" newline="true"><text>Bookmark Toolbar</text> +</ToolBar> +<ActionProperties> + <Action shortcut="F9" name="konq_sidebartng" /> +</ActionProperties> + +</gui> + diff --git a/konqueror/konquerorsu.desktop b/konqueror/konquerorsu.desktop new file mode 100644 index 000000000..72ac0ba07 --- /dev/null +++ b/konqueror/konquerorsu.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Type=Application +Exec=konqueror --profile filemanagement +DocPath=konqueror/index.html +Icon=kfm +X-KDE-SubstituteUID=true + +Name=File Manager - Super User Mode +Name[af]=Lêer Bestuurder - Super Gebruiker Modus +Name[ar]=مدبر الملفات - نمط المستخدم الجذري +Name[az]=Fayl İdarəçisi - Ali İstifadəçi Modu +Name[be]=Кіраўнік файлаў - рэжым адміністратара +Name[bg]=Файлов браузър - администратор +Name[bn]=ফাইল ম্যানেজার - অ্যাডমিনস্ট্রেটর মোড +Name[br]=Merour restroù - Doare gourarveriad +Name[bs]=Upravitelj datotekama (Samo za administratora) +Name[ca]=Gestor de fitxers (mode superusuari) +Name[cs]=Správce souborů - superuživatelský režim +Name[csb]=Menedżer lopków - trib sprôwnika +Name[cy]=Trefnydd Ffeiliau - Modd Defnyddiwr Uwch +Name[da]=Filhåndtering (superbruger-tilstand) +Name[de]=Konqueror (Systemverwaltungsmodus) +Name[el]=Διαχειριστής αρχείων - Λειτουργία ως root +Name[eo]=Dosieradministrilo (kiel sistemestro) +Name[es]=Gestor de archivos - modo superusuario +Name[et]=Failihaldur (administraator) +Name[eu]=Fitxategi kudeatzailea (root era) +Name[fa]=مدیر پرونده - حالت ابرکاربر +Name[fi]=Tiedostonhallinta - pääkäyttäjätila +Name[fr]=Konqueror (mode superutilisateur) +Name[fy]=Triembehearder (yn systeembehearmodus) +Name[ga]=Bainisteoir Comhad - Mód Forúsáideora +Name[gl]=Xestor de Ficheiros - Modo Super-Usuario +Name[he]=מנהל קבצים - מצב משתמש־על +Name[hi]=फ़ाइल प्रबंधक- सुपर यूजर मोड +Name[hr]=Upravitelj datotekama - za administratora +Name[hu]=Fájlkezelő (rendszergazdai mód) +Name[is]=Skráastjóri (sem kerfisstjóri) +Name[it]=File manager - modalità super utente +Name[ja]=ファイルマネージャ - スーパーユーザモード +Name[ka]=ფაილური მენეჯერი (root-ის პრივილეგიებით) +Name[kk]=Файл менеджері (root құқықлы) +Name[km]=កម្មវិធីគ្រប់គ្រងឯកសារ - របៀបអ្នកប្រើជាន់ខ្ពស់ +Name[ko]=파일 관리자 - 슈퍼유저 모드 +Name[lo]=ຕົວຈັດການແຟ້ມ - ໂຫມດຜູ້ດູແລລະບົບ +Name[lt]=Bylų tvarkyklė – super naudotojo veiksena +Name[lv]=Failu Pārvaldnieks - Super Lietotāja Režīms +Name[mk]=Менаџер на датотеки - режим root +Name[mn]=Конкюрор (Системийн удирдлагын-Горим) +Name[ms]=Pengurus Fail - Mod Pengguna Super +Name[mt]=Manager tal-Fajls (mod Super User) +Name[nb]=Filbehandler – superbrukermodus +Name[nds]=Dateipleger, Systeempleegbedrief +Name[ne]=फाइल प्रबन्धक - सुपर प्रयोगकर्ता मोड +Name[nl]=Bestandsbeheerder (in systeembeheermodus) +Name[nn]=Filhandsamar – Superbrukarmodus +Name[nso]=Molaodi wa Faele - Seripa sa Modirisi yo Maatla +Name[pa]=ਫਾਇਲ ਮੈਨੇਜਰ - ਸੁਪਰ ਉਪਭੋਗੀ (ਮੈਨੇਜਰੀ) ਢੰਗ +Name[pl]=Menedżer plików - tryb administratora +Name[pt]=Gestor de Ficheiros - Modo de Super Utilizador +Name[pt_BR]=Gerenciador de Arquivos (Modo Super-Usuário) +Name[ro]=Manager de fișiere - mod superutilizator +Name[ru]=Менеджер файлов (в режиме администратора) +Name[rw]=Mucungadosiye - Uburyo Ukoresha Mukuru +Name[se]=Fiilagieđahalli – Supergeavaheaddjemodus +Name[sk]=Správca súborov - Super-používateľský mód +Name[sl]=Upravitelj datotek (skrbniški način) +Name[sr]=Менаџер фајлова — режим супер корисника +Name[sr@Latn]=Menadžer fajlova — režim super korisnika +Name[sv]=Filhanterare - Administratörsläge +Name[ta]=கோப்பு மேலாளர் - மீப்பயனர் முறைமை +Name[te]=దస్త్ర అభికర్త - సూపర్ యూజర్ స్థితి +Name[tg]=Мудири файл - ҳолати убури корбар +Name[th]=ตัวจัดการแฟ้ม - โหมดผู้ดูแลระบบ +Name[tr]=Dosya Yöneticisi - Yetkili Kullanıcı +Name[tt]=Birem-İdäräçe (root ısulı) +Name[uk]=Менеджер файлів (режим адміністратора) +Name[uz]=Fayl boshqaruvchisi (root) +Name[uz@cyrillic]=Файл бошқарувчиси (root) +Name[ven]=Mulanguli wa faela - mushumisi wa muhulwana wa moudu +Name[vi]=Trình quản lí Tập tin - Dành cho người quản lý +Name[wa]=Manaedjeu di fitchîs - Môde super uzeu (root) +Name[xh]=Umphathi Wefayile - Indlela Ephezulu Yomsebenzisi +Name[zh_CN]=文件管理器 - 超级用户模式 +Name[zh_TW]=檔案總管 - 超級使用者模式 +Name[zu]=Imenenja yamafayela - Indlela Yomsebenzisi Omkhulu + + +Categories=Qt;KDE;System;X-KDE-More; +NotShowIn=GNOME; diff --git a/konqueror/kttsplugin/Makefile.am b/konqueror/kttsplugin/Makefile.am new file mode 100644 index 000000000..580a18dcd --- /dev/null +++ b/konqueror/kttsplugin/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = $(all_includes) +METASOURCES = AUTO + +# Install this plugin in the KDE modules directory +kde_module_LTLIBRARIES = libkhtmlkttsdplugin.la + +libkhtmlkttsdplugin_la_SOURCES = khtmlkttsd.cpp +libkhtmlkttsdplugin_la_LIBADD = $(LIB_KHTML) +libkhtmlkttsdplugin_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) + +pluginsdir = $(kde_datadir)/khtml/kpartplugins +plugins_DATA = khtmlkttsd.rc khtmlkttsd.desktop + +messages: rc.cpp + $(EXTRACTRC) *.rc > rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/khtmlkttsd.pot diff --git a/konqueror/kttsplugin/khtmlkttsd.cpp b/konqueror/kttsplugin/khtmlkttsd.cpp new file mode 100644 index 000000000..cda947223 --- /dev/null +++ b/konqueror/kttsplugin/khtmlkttsd.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** + Copyright: + (C) 2002 by George Russell <[email protected]> + (C) 2003-2004 by Olaf Schmidt <[email protected]> + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <khtml_part.h> // this plugin applies to a khtml part +#include <dom/html_document.h> +#include <dom/html_element.h> +#include <dom/dom_string.h> +#include <kdebug.h> +#include "khtmlkttsd.h" +#include <kaction.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <qmessagebox.h> +#include <klocale.h> +#include <qstring.h> +#include <qtimer.h> +#include <kspeech.h> +#include <qbuffer.h> + +#include <kapplication.h> +#include <dcopclient.h> +#include <ktrader.h> + +KHTMLPluginKTTSD::KHTMLPluginKTTSD( QObject* parent, const char* name, const QStringList& ) + : Plugin( parent, name ) +{ + // If KTTSD is not installed, hide action. + KTrader::OfferList offers = KTrader::self()->query("DCOP/Text-to-Speech", "Name == 'KTTSD'"); + if (offers.count() > 0) + { + (void) new KAction( i18n("&Speak Text"), + "kttsd", 0, + this, SLOT(slotReadOut()), + actionCollection(), "tools_kttsd" ); + } + else + kdDebug() << "KHTMLPLuginKTTSD::KHTMLPluginKTTSD: KTrader did not find KTTSD." << endl; +} + +KHTMLPluginKTTSD::~KHTMLPluginKTTSD() +{ +} + +void KHTMLPluginKTTSD::slotReadOut() +{ + // The parent is assumed to be a KHTMLPart + if ( !parent()->inherits("KHTMLPart") ) + QMessageBox::warning( 0, i18n( "Cannot Read source" ), + i18n( "You cannot read anything except web pages with\n" + "this plugin, sorry." )); + else + { + // If KTTSD not running, start it. + DCOPClient *client = kapp->dcopClient(); + if (!client->isApplicationRegistered("kttsd")) + { + QString error; + if (kapp->startServiceByDesktopName("kttsd", QStringList(), &error)) + QMessageBox::warning(0, i18n( "Starting KTTSD Failed"), error ); + } + + // Find out if KTTSD supports xhtml (rich speak). + QByteArray data; + QBuffer dataBuf(data); + QDataStream arg; + dataBuf.open(IO_WriteOnly); + arg.setDevice(&dataBuf); + arg << "" << KSpeech::mtHtml; + QCString replyType; + QByteArray replyData; + bool supportsXhtml = false; + if ( !client->call("kttsd", "KSpeech", "supportsMarkup(QString,uint)", + data, replyType, replyData, true) ) + QMessageBox::warning( 0, i18n( "DCOP Call Failed" ), + i18n( "The DCOP call supportsMarkup failed." )); + else + { + QDataStream reply(replyData, IO_ReadOnly); + reply >> supportsXhtml; + } + + KHTMLPart *part = (KHTMLPart *) parent(); + + QString query; + if (supportsXhtml) + { + kdDebug() << "KTTS claims to support rich speak (XHTML to SSML)." << endl; + if (part->hasSelection()) + query = part->selectedTextAsHTML(); + else + { + // TODO: Fooling around with the selection probably has unwanted + // side effects, but until a method is supplied to get valid xhtml + // from entire document.. + // query = part->document().toString().string(); + part->selectAll(); + query = part->selectedTextAsHTML(); + // Restore no selection. + part->setSelection(part->document().createRange()); + } + } else { + if (part->hasSelection()) + query = part->selectedText(); + else + query = part->htmlDocument().body().innerText().string(); + } + // kdDebug() << "KHTMLPluginKTTSD::slotReadOut: query = " << query << endl; + + dataBuf.at(0); // reset data + arg << query << ""; + if ( !client->call("kttsd", "KSpeech", "setText(QString,QString)", + data, replyType, replyData, true) ) + QMessageBox::warning( 0, i18n( "DCOP Call Failed" ), + i18n( "The DCOP call setText failed." )); + dataBuf.at(0); + arg << 0; + if ( !client->call("kttsd", "KSpeech", "startText(uint)", + data, replyType, replyData, true) ) + QMessageBox::warning( 0, i18n( "DCOP Call Failed" ), + i18n( "The DCOP call startText failed." )); + } +} + +K_EXPORT_COMPONENT_FACTORY( libkhtmlkttsdplugin, KGenericFactory<KHTMLPluginKTTSD>("khtmlkttsd") ) + +#include "khtmlkttsd.moc" diff --git a/konqueror/kttsplugin/khtmlkttsd.desktop b/konqueror/kttsplugin/khtmlkttsd.desktop new file mode 100644 index 000000000..96bfcafeb --- /dev/null +++ b/konqueror/kttsplugin/khtmlkttsd.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +X-KDE-Library=libkhtmlkttsdplugin +X-KDE-PluginInfo-Author=Olaf Schmidt +X-KDE-PluginInfo-Name=khtmlkttsdplugin +X-KDE-PluginInfo-Version=3.4 +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category=Tools +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-ParentApp=konqueror +Name=Text-to-Speech Plugin +Name[ar]=برنامج مساعد تحويل لفظ النص +Name[be]=Утулка галасавога ўзнаўлення тэксту +Name[bg]=Приставка за синтез на глас +Name[bn]=লেখা-থেকে-বলা প্লাগ-ইন +Name[bs]=Dodatak za izgovaranje teksta +Name[ca]=Endollable de text a veu +Name[cs]=Modul text-na-řeč +Name[csb]=Plugins czëtôrza tekstu +Name[da]=Tekst-til-tale plugin +Name[de]=Sprachausgabe-Plugin +Name[el]=Πρόσθετο κείμενο σε ομιλία +Name[eo]=Teksto-Paroligilo Kromaĵo +Name[es]=Complemento de Texto-a-Voz +Name[et]=Teksti kõneks muutmise plugin +Name[eu]=Testu-ahotserako plugina +Name[fa]=وصلۀ متن به سخن +Name[fi]=Teksti puheeksi -liitännäinen +Name[fr]=Module de synthèse vocale +Name[fy]=Tekst-ta-spraak-plugin +Name[ga]=Breiseán Téacs-go-Caint +Name[gl]=Plugin de Texto-a-Fala +Name[he]=תוסף טקסט אל דיבור +Name[hr]=Pretvaranje teksta u govor +Name[hu]=Szövegfelolvasó modul +Name[is]=Texti-í-tal íforrit +Name[it]=Plugin lettura del testo (text-to-speech) +Name[ja]=テキスト読み上げプラグイン +Name[ka]=ტექსტის გახმოვანების მოდული +Name[kk]=Дыбыстап оқу модулі +Name[km]=កម្មវិធីជំនួយខាងក្នុង អត្ថបទ-ទៅជា-សម្ដី +Name[ko]=Text-to-Speech +Name[lt]=Teksto vertimo kalba priedas +Name[mk]=Приклучок за текст-во-говор +Name[ms]=Plugin Teks-ke-Tutur +Name[nb]=Programtillegg for tekst-til-tale +Name[nds]=Vörleser-Plugin +Name[ne]=पाठलाई वाक्यमा प्लगइन +Name[nl]=Tekst-tot-spraak-plugin +Name[nn]=Programtillegg for tekst-til-tale +Name[pa]=ਪਾਠ ਤੋਂ ਬੋਲੀ ਪਲੱਗਇਨ +Name[pl]=Wtyczka odczytywania tekstu +Name[pt]='Plugin' de Texto-para-Fala +Name[pt_BR]=Plug-in de Conversão de Fala +Name[ro]=Modul vorbire text +Name[ru]=Зачитывание текста +Name[rw]=Icomeka Umwandiko-ku-Imvugo +Name[sk]=Modul text-na-reč +Name[sl]=Vstavek za pretvorbo besedila v govor +Name[sr]=Прикључак за текст-у-говор +Name[sr@Latn]=Priključak za tekst-u-govor +Name[sv]=Text till tal-insticksprogram +Name[ta]=உரையில் இருந்து பேச்சு சொருகுப்பொருள் +Name[th]=ปลั๊กอิน เปลี่ยนตัวหนังสือเป็นเสียง +Name[tr]=Metinden-Sese Eklentisi +Name[tt]=Yazma-Uquçı Östämä +Name[uk]=Втулок синтезу мовлення з тексту +Name[vi]=Trình bổ sung Chuyển Văn bản thành Tiếng nói +Name[wa]=Tchôke-divins tecse viè parole +Name[zh_CN]=文本到语音插件 +Name[zh_TW]=文字轉換語音外掛程式 +Icon=kttsd + diff --git a/konqueror/kttsplugin/khtmlkttsd.h b/konqueror/kttsplugin/khtmlkttsd.h new file mode 100644 index 000000000..aa1608498 --- /dev/null +++ b/konqueror/kttsplugin/khtmlkttsd.h @@ -0,0 +1,46 @@ +/*************************************************************************** + Copyright: + (C) 2002 by George Russell <[email protected]> + (C) 2003-2004 by Olaf Schmidt <[email protected]> + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifndef KHTMLKTTSD_H +#define KHTMLKTTSD_H + +#include <kparts/plugin.h> + +class KURL; +class KInstance; + +/** + * KHTML KParts Plugin + */ +class KHTMLPluginKTTSD : public KParts::Plugin +{ + Q_OBJECT +public: + + /** + * Construct a new KParts plugin. + */ + KHTMLPluginKTTSD( QObject* parent, const char* name, const QStringList& ); + + /** + * Destructor. + */ + virtual ~KHTMLPluginKTTSD(); +public slots: + void slotReadOut(); +}; + +#endif diff --git a/konqueror/kttsplugin/khtmlkttsd.rc b/konqueror/kttsplugin/khtmlkttsd.rc new file mode 100644 index 000000000..388aec9e7 --- /dev/null +++ b/konqueror/kttsplugin/khtmlkttsd.rc @@ -0,0 +1,13 @@ +<!DOCTYPE kpartgui> +<kpartgui name="khtmlkttsdplugin" library="libkhtmlkttsdplugin" version="2" > + <MenuBar> + <Menu name="tools"> + <Text>&Tools</Text> + <Action name="tools_kttsd"/> + </Menu> + </MenuBar> + <ToolBar name="Speech Toolbar" hidden="true"> + <Action name="tools_kttsd"/> + </ToolBar> +</kpartgui> + diff --git a/konqueror/listview/Makefile.am b/konqueror/listview/Makefile.am new file mode 100644 index 000000000..91dd33a10 --- /dev/null +++ b/konqueror/listview/Makefile.am @@ -0,0 +1,30 @@ + +INCLUDES = -I$(top_srcdir)/libkonq -I$(top_srcdir)/konqueror $(all_includes) + +kde_module_LTLIBRARIES = konq_listview.la + +METASOURCES = AUTO + +konq_listview_la_SOURCES = konq_listview.cc \ + konq_listviewwidget.cc konq_listviewitems.cc \ + konq_treeviewwidget.cc konq_treeviewitem.cc \ + konq_textviewwidget.cc konq_textviewitem.cc \ + konq_infolistviewwidget.cc konq_infolistviewitem.cc \ + konq_listviewsettings.kcfgc + +konq_listview_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +konq_listview_la_LIBADD = $(top_builddir)/libkonq/libkonq.la + +kde_services_DATA = konq_treeview.desktop konq_detailedlistview.desktop \ + konq_textview.desktop konq_infolistview.desktop + +rcdir = $(kde_datadir)/konqlistview +rc_DATA = konq_treeview.rc konq_detailedlistview.rc konq_textview.rc \ + konq_infolistview.rc + +kde_kcfg_DATA = konq_listview.kcfg + +####### Build rules +konq_listview.lo: konq_listviewsettings.h +konq_listviewsettings.lo: konq_listviewsettings.h +konq_listviewwidget.lo: konq_listviewsettings.h diff --git a/konqueror/listview/konq_detailedlistview.desktop b/konqueror/listview/konq_detailedlistview.desktop new file mode 100644 index 000000000..9dc4938bd --- /dev/null +++ b/konqueror/listview/konq_detailedlistview.desktop @@ -0,0 +1,89 @@ +[Desktop Entry] +Type=Service +Name=Detailed List View +Name[af]=Gedetaileerde Lys Besigtig +Name[ar]=عرض مفصل لوحي +Name[az]=Ətraflı Siyahı Görünüşü +Name[be]=Падрабязны спіс +Name[bg]=Подробен преглед +Name[bn]=বিস্তারিত তালিকা ভিউ +Name[br]=Gwell roll gant munudoù +Name[bs]=Pogled detaljne liste +Name[ca]=Vista de llista detallada +Name[cs]=Detailní pohled +Name[csb]=Wëzdrzatk z akùratną lëstą +Name[cy]=Golwg Rhestr Fanwl +Name[da]=Detaljeret listevisning +Name[de]=Detaillierte Ordneransicht +Name[el]=Προβολή λεπτομερούς λίστας +Name[eo]=Detala listrigardo +Name[es]=Vista de lista detallada +Name[et]=Vaade detailse nimekirjana +Name[eu]=Xehetasundun zerrenda ikuspegia +Name[fa]=نمای فهرست جزئیات +Name[fi]=Yksityiskohtainen listanäkymä +Name[fr]=Liste détaillée +Name[fy]=detaillearre werjefte +Name[ga]=Amharc Liosta Mion +Name[gl]=Vista en Lista Detallada +Name[he]=תצוגת פרטים +Name[hi]=विस्तृत सूची दृश्य +Name[hr]=Detaljan prikaz +Name[hu]=Lista (részletes) +Name[id]=Tampilan list secara detail +Name[is]=Ýtarleg sýn, listi +Name[it]=Vista a lista dettagliata +Name[ja]=詳細なリストビュー +Name[ka]=დაწვრილებითი დიის ხილვა +Name[kk]=Егжей-тегжейлі тізім +Name[km]=ទិដ្ឋភាពបញ្ជីលម្អិត +Name[lo]=ມຸມມອງແບບລາບລະອງດ +Name[lt]=Rodyti detalų sąrašą +Name[lv]=Detalizēta saraksta skatījums +Name[mk]=Преглед со детална листа +Name[mn]=Нарийвчилсан жагсаалтаар харах +Name[ms]=Paparan Senarai Terperinci +Name[mt]=Uri Lista Dettaljata +Name[nb]=Detaljert listevisning +Name[nds]=Detailleerte List +Name[ne]=विस्तृत सूची दृश्य +Name[nl]=Gedetailleerde weergave +Name[nn]=Detaljert listevising +Name[nso]=Pono yeo e Tseneletsego ya Palo +Name[pa]=ਵੇਰਵਾ ਸੂਚੀ ਝਲਕ +Name[pl]=Widok ze szczegółową listą +Name[pt]=Vista em Lista Detalhada +Name[pt_BR]=Visão de Lista Detalhada +Name[ro]=Vizualizare listă detaliată +Name[ru]=В виде подробного списка +Name[rw]=Igaragaza ry'Urutonde Rusesenguye +Name[se]=Bienalaš listočájeheapmi +Name[sk]=Detailný zoznam +Name[sl]=Pogled podrobnega seznama +Name[sr]=Детаљан приказ (листа) +Name[sr@Latn]=Detaljan prikaz (lista) +Name[sv]=Detaljerad listvy +Name[ta]=விவரமான பட்டியல் காட்சி +Name[te]=వివరణాత్మక జాబితా వీక్షణం +Name[tg]=Ба намуди саҳифаи ҷузъиёт +Name[th]=มุมมองแบบรายละเอียด +Name[tr]=Ayrıntılı Liste Görünümü +Name[tt]=Täfsille Tezmädä Küreneş +Name[uk]=Детальний вигляд списком +Name[uz]=Batafsil roʻyxat koʻrinishida +Name[uz@cyrillic]=Батафсил рўйхат кўринишида +Name[ven]=Mbonalelo ya mutevhe wo bviselwaho khagala +Name[vi]=Xem kiểu Danh sách Đầy đủ +Name[wa]=Vey en ene sipepieuse djivêye +Name[xh]=Imboniselo Yoluhlu Oluneenkcukacha +Name[zh_CN]=细节列表视图 +Name[zh_TW]=詳細的清單檢視 +Name[zu]=Umbukiso Woluhlu Oluneminingwane +MimeType=inode/directory +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=DetailedList +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_detailed +InitialPreference=7 diff --git a/konqueror/listview/konq_detailedlistview.rc b/konqueror/listview/konq_detailedlistview.rc new file mode 100644 index 000000000..593e7f027 --- /dev/null +++ b/konqueror/listview/konq_detailedlistview.rc @@ -0,0 +1,52 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqDetailedListView" version="11"> +<MenuBar> + <Menu name="edit"><text>&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>&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> + <Separator/> + <Action name="show_dot"/> + <Action name="sort_caseinsensitive"/> + <!--<Action name="sort_directoriesfirst" /> TODO --> + <Menu name="listview_show"><text>Show Details</text> + <TearOffHandle /> + <Action name="show_size"/> + <Action name="show_type"/> + <Action name="show_mimetype"/> + <Action name="show_url"/> + <Action name="show_time"/> + <Action name="show_access_time"/> + <Action name="show_creation_time"/> + <Action name="show_permissions"/> + <Action name="show_owner"/> + <Action name="show_group"/> + <Action name="show_link_dest"/> + </Menu> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar"><text>Detailed Listview Toolbar</text> + <Separator/> + <Action name="incIconSize" /> + <Action name="decIconSize" /> +</ToolBar> +</kpartgui> diff --git a/konqueror/listview/konq_infolistview.desktop b/konqueror/listview/konq_infolistview.desktop new file mode 100644 index 000000000..12186d8f7 --- /dev/null +++ b/konqueror/listview/konq_infolistview.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Type=Service +Name=Info List View +Name[af]=Inligting Lys Besigtig +Name[ar]=عرض معلومات لوحي +Name[az]=Məlumat Siyahı Görünüşü +Name[be]=Інфармацыйны спіс +Name[bg]=Информационен преглед +Name[bn]=তথ্য তালিকা ভিউ +Name[bs]=Pogled info liste +Name[ca]=Vista de llista informativa +Name[cs]=Pohled s informačním seznamem +Name[csb]=Wëzdrzatk wëdowiédny lëstë +Name[cy]=Golwg Rhestr Gwybodaeth +Name[da]=Info-listevisning +Name[de]=Infolistenansicht +Name[el]=Προβολή λίστας πληροφοριών +Name[eo]=Inforigardo +Name[es]=Vista de lista de información +Name[et]=Infonimekirja vaade +Name[eu]=Info zerrenda ikuspegia +Name[fa]=نمای فهرست اطلاعات +Name[fi]=Infolistanäkymä +Name[fr]=Affichage de liste info +Name[fy]=Ynfolistwerjefte +Name[ga]=Amharc Liosta Eolais +Name[gl]=Vista en Lista Informativa +Name[he]=תצוגת רשימה +Name[hi]=जानकारी सूची दृश्य +Name[hr]=Prikaz info-popisa +Name[hu]=Lista (rövid) +Name[is]=Upplýsingalisti +Name[it]=Vista informazioni +Name[ja]=情報リストビュー +Name[ka]=სია აღწერით +Name[kk]=Мәліметті тізім +Name[km]=ទិដ្ឋភាពព័ត៌មានលម្អិត +Name[lo]=ມຸມມອງແບບໄອຄອນ +Name[lt]=Rodyti info sąrašą +Name[lv]=Info saraksta skatījums +Name[mk]=Преглед со инфо. листа +Name[mn]=Мэд. жагсаалтаар харах +Name[ms]=Paparan Senarai Maklumat +Name[mt]=Lista info. +Name[nb]=Infolistevisning +Name[nds]=Infolistansicht +Name[ne]=सूचना सूची दृश्य +Name[nl]=Infolijstweergave +Name[nn]=Infolistevising +Name[nso]=Pono ya Palo ya Tshedimoso +Name[pa]=ਜਾਣਕਾਰੀ ਸੂਚੀ ਝਲਕ +Name[pl]=Widok listy informacyjnej +Name[pt]=Vista em Lista com Informações +Name[pt_BR]=Visão de Lista de Informações +Name[ro]=Vizualizare listă de informații +Name[ru]=В виде списка с описанием +Name[rw]=Igaragaza Urutonde Amakuru +Name[se]=Diehtolistočájeheapmi +Name[sk]=Zoznam s informáciami +Name[sl]=Pogled seznama z informacijami +Name[sr]=Приказ инфо листе +Name[sr@Latn]=Prikaz info liste +Name[sv]=Info-listvy +Name[ta]=தகவல் பட்டியல் காட்சி +Name[te]=సమాచార జాబితా వీక్షణం +Name[tg]=Ба намуди саҳифаи иттилоот +Name[th]=มุมมองแบบรายการข้อมูล +Name[tr]=Bilgi Listesi Görünümü +Name[tt]=Qısqa Tezmädäy Küreneş +Name[uk]=Вигляд з інформацією про зміст +Name[uz]=Maʼlumotli roʻyxat koʻrinishida +Name[uz@cyrillic]=Маълумотли рўйхат кўринишида +Name[ven]=Mbonalelo ya mutevhe wa mafhungo +Name[vi]=Xem kiểu Danh sách Thông tin +Name[wa]=Vey les informåcions en ene djivêye +Name[xh]=Imboniselo Yoluhlu Lolwazi +Name[zh_CN]=信息列表视图 +Name[zh_TW]=資訊清單檢視 +Name[zu]=Umbukiso wohlu lolwazi +MimeType=inode/directory +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=InfoListView +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_detailed +InitialPreference=7 diff --git a/konqueror/listview/konq_infolistview.rc b/konqueror/listview/konq_infolistview.rc new file mode 100644 index 000000000..280b2d0ce --- /dev/null +++ b/konqueror/listview/konq_infolistview.rc @@ -0,0 +1,39 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqInfoListView" version="12"> +<MenuBar> + <Menu name="edit"><text>&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>&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> + <Separator/> + <Action name="show_dot"/> + <Action name="sort_caseinsensitive"/> + <!--<Action name="sort_directoriesfirst" /> TODO --> + <Action name="view_as"/> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar"><text>Info Listview Toolbar</text> + <Separator/> + <Action name="incIconSize" /> + <Action name="decIconSize" /> +</ToolBar> +</kpartgui> diff --git a/konqueror/listview/konq_infolistviewitem.cc b/konqueror/listview/konq_infolistviewitem.cc new file mode 100644 index 000000000..02aac1d07 --- /dev/null +++ b/konqueror/listview/konq_infolistviewitem.cc @@ -0,0 +1,281 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus <[email protected]> + + 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 version 2.0 + + 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_listview.h" +#include <konq_settings.h> +#include <kfilemetainfo.h> +#include <kdebug.h> +#include <klocale.h> +#include <assert.h> +#include <stdio.h> +#include <qpainter.h> +#include <qheader.h> +#include <kiconloader.h> +#include "konq_infolistviewitem.h" +#include "konq_infolistviewwidget.h" + +/************************************************************** + * + * KonqInfoListViewItem + * + **************************************************************/ +KonqInfoListViewItem::KonqInfoListViewItem( KonqInfoListViewWidget *_widget, KonqInfoListViewItem * _parent, KFileItem* _fileitem ) +:KonqBaseListViewItem( _widget,_parent,_fileitem ), m_ILVWidget(_widget) +{ + updateContents(); +} + +KonqInfoListViewItem::KonqInfoListViewItem( KonqInfoListViewWidget *_listViewWidget, KFileItem* _fileitem ) +:KonqBaseListViewItem(_listViewWidget,_fileitem), m_ILVWidget(_listViewWidget) +{ + updateContents(); +} + +void KonqInfoListViewItem::updateContents() +{ + // Set the pixmap + setDisabled( m_bDisabled ); + + // Set the text of each column + setText(0,m_fileitem->text()); + +#if 0 + if (S_ISDIR(m_fileitem->mode())) + sortChar='0'; + //now we have the first column, so let's do the rest + + for (unsigned int i=0; i<KonqBaseListViewWidget::NumberOfAtoms; i++) + { + ColumnInfo *tmpColumn=&static_cast<KonqBaseListViewWidget *>(listView())->columnConfigInfo()[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case KIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case KIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case KIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case KIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case KIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case KIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case KIO::UDS_SIZE: + if ( static_cast<KonqBaseListViewWidget *>(listView())->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatNumber( m_fileitem->size(),0)+" "); + else + setText(tmpColumn->displayInColumn,KIO::convertSize(m_fileitem->size())+" "); + break; + case KIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + QDateTime dt; + time_t _time = m_fileitem->time( tmpColumn->udsId ); + if ( _time != 0 ) + { + dt.setTime_t( _time ); + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatDateTime(dt)); + } + } + break; + default: + break; + }; + }; + }; +#endif +} + +void KonqInfoListViewItem::gotMetaInfo() +{ + KFileMetaInfo info = item()->metaInfo(false); + + if (!info.isValid()) return; + + QStringList::ConstIterator it = m_ILVWidget->columnKeys().begin(); + for (int i = 1; it != m_ILVWidget->columnKeys().end(); ++it, ++i) + { + KFileMetaInfoItem kfmii = info.item(*it); + + m_columnTypes.append(kfmii.type()); + m_columnValues.append(kfmii.value()); + + if (!kfmii.isValid()) + continue; + + QString s = kfmii.string().simplifyWhiteSpace(); + setText(i, s.isNull() ? QString("") : s); + } +} + +int KonqInfoListViewItem::compare( QListViewItem *item, int col, bool ascending ) const +{ + if ( col == 0 ) + return KonqBaseListViewItem::compare( item, 0, ascending ); + + KonqInfoListViewItem *i = static_cast<KonqInfoListViewItem *>(item); + + int size1 = m_columnValues.size(); + int size2 = i->m_columnValues.size(); + + if ( size1 < col || size2 < col ) + return ascending ? ( size2 - size1 ) : ( size1 - size2 ); + + QVariant value1 = m_columnValues[ col-1 ]; + QVariant value2 = i->m_columnValues[ col-1 ]; + QVariant::Type type1 = m_columnTypes[ col-1 ]; + QVariant::Type type2 = i->m_columnTypes[ col-1 ]; + + if ( type1 != type2 ) + return ascending ? ( type1 - type2 ) : ( type2 - type1 ); + +#define KONQ_CASE( x ) \ + case QVariant::x:\ + return ( value1.to##x() > value2.to##x() ) ? 1 : ( value1.to##x() == value2.to##x() ) ? 0 : -1; + + switch( type1 ) { + KONQ_CASE( Bool ) + KONQ_CASE( Int ) + KONQ_CASE( LongLong ) + KONQ_CASE( UInt ) + KONQ_CASE( ULongLong ) + KONQ_CASE( Double ) + KONQ_CASE( Date ) + KONQ_CASE( Time ) + KONQ_CASE( DateTime ) + case QVariant::Size: + { + int w1 = value1.toSize().width(); + int w2 = value2.toSize().width(); + if ( w1 != w2 ) + return ( w1 > w2 ) ? 1 : -1; + int h1 = value1.toSize().height(); + int h2 = value2.toSize().height(); + return ( h1 > h2 ) ? 1 : ( h1 == h2 ) ? 0 : -1; + } + default: + break; + } +#undef KONQ_CASE + + QString text1 = text(col); + QString text2 = i->text(col); + + if ( text1.isEmpty() ) + return ascending ? 1 : -1; + if ( text2.isEmpty() ) + return ascending ? -1 : 1; + + return text1.lower().localeAwareCompare(text2.lower()); +} + +void KonqInfoListViewItem::setDisabled( bool disabled ) +{ + KonqBaseListViewItem::setDisabled( disabled ); + int iconSize = static_cast<KonqBaseListViewWidget *>(listView())->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqInfoListViewItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + QColorGroup cg( _cg ); + + if ( _column == 0 ) + { + _painter->setFont( m_pListViewWidget->itemFont() ); + } + + cg.setColor( QColorGroup::Text, m_pListViewWidget->itemColor() ); + + KListView *lv = static_cast< KListView* >( listView() ); + const QPixmap *pm = lv->viewport()->paletteBackgroundPixmap(); + if ( _column == 0 && isSelected() && !lv->allColumnsShowFocus() ) + { + int newWidth = width( lv->fontMetrics(), lv, _column ); + if ( newWidth > _width ) + newWidth = _width; + if ( pm && !pm->isNull() ) + { + cg.setBrush( QColorGroup::Base, QBrush( backgroundColor(_column), *pm ) ); + QPoint o = _painter->brushOrigin(); + _painter->setBrushOrigin( o.x() - lv->contentsX(), o.y() - lv->contentsY() ); + const QColorGroup::ColorRole crole = + QPalette::backgroundRoleFromMode( lv->viewport()->backgroundMode() ); + _painter->fillRect( newWidth, 0, _width - newWidth, height(), cg.brush( crole ) ); + _painter->setBrushOrigin( o ); + } + else + { + _painter->fillRect( newWidth, 0, _width - newWidth, height(), backgroundColor(_column) ); + } + + _width = newWidth; + } + + KListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +void KonqInfoListViewItem::paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & _r ) +{ + QRect r( _r ); + QListView *lv = static_cast< QListView * >( listView() ); + r.setWidth( width( lv->fontMetrics(), lv, 0 ) ); + if ( r.right() > lv->header()->sectionRect( 0 ).right() ) + r.setRight( lv->header()->sectionRect( 0 ).right() ); + QListViewItem::paintFocus( _painter, cg, r ); +} + +#if 0 +void KonqBaseListViewItem::mimetypeFound() +{ + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = static_cast<KonqBaseListViewWidget*>(listView()); + for (unsigned int i=0; i<KonqBaseListViewWidget::NumberOfAtoms && done < 2; i++) + { + ColumnInfo *tmpColumn=&lv->columnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_MIME_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimetype()); + done++; + } + } +} + +#endif diff --git a/konqueror/listview/konq_infolistviewitem.h b/konqueror/listview/konq_infolistviewitem.h new file mode 100644 index 000000000..886ba66af --- /dev/null +++ b/konqueror/listview/konq_infolistviewitem.h @@ -0,0 +1,79 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus <[email protected]> + + 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 version 2.0 + + 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 __konq_infolistviewitems_h__ +#define __konq_infolistviewitems_h__ + +#include "konq_listview.h" +#include <qstring.h> +#include <kicontheme.h> + +// for mode_t +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +class QPainter; +class KFileItem; +class KonqInfoListViewWidget; + +/** + * One item in the info list + */ +class KonqInfoListViewItem : public KonqBaseListViewItem +{ + public: + /** + * Create an item in the tree toplevel representing a file + * @param _parent the parent widget, the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqInfoListViewItem( KonqInfoListViewWidget *_listViewWidget, KFileItem* _fileitem ); + /** + * Create an item representing a file, inside a directory + * @param _treeview the parent tree view - now unused + * @param _parent the parent widget, a directory item in the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqInfoListViewItem( KonqInfoListViewWidget *, KonqInfoListViewItem *_parent, KFileItem* _fileitem ); + + virtual ~KonqInfoListViewItem() { } + + virtual void paintCell( QPainter *_painter, const QColorGroup & cg, + int column, int width, int alignment ); + virtual void paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & r ); + virtual void updateContents(); + virtual void setDisabled( bool disabled ); + + virtual void gotMetaInfo(); + + virtual int compare(QListViewItem *item, int col, bool ascending) const; + + protected: + /** + * Parent tree view - the info list view widget + */ + KonqInfoListViewWidget* m_ILVWidget; + + private: + QValueVector<QVariant::Type> m_columnTypes; + QValueVector<QVariant> m_columnValues; +}; + +#endif diff --git a/konqueror/listview/konq_infolistviewwidget.cc b/konqueror/listview/konq_infolistviewwidget.cc new file mode 100644 index 000000000..c9ef4b0e4 --- /dev/null +++ b/konqueror/listview/konq_infolistviewwidget.cc @@ -0,0 +1,383 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + 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 version 2.0 + + 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_infolistviewwidget.h" +#include "konq_infolistviewwidget.moc" +#include "konq_infolistviewitem.h" +#include "konq_listview.h" + +#include <klocale.h> +#include <kfilemetainfo.h> +#include <kdebug.h> +#include <kaction.h> +#include <kservicetype.h> +#include <kuserprofile.h> +#include <kio/metainfojob.h> + +#include <qstringlist.h> + +KonqInfoListViewWidget::KonqInfoListViewWidget( KonqListView* parent, + QWidget* parentWidget) + : KonqBaseListViewWidget(parent, parentWidget) +{ + m_metaInfoJob = 0; + + m_mtSelector = new KSelectAction(i18n("View &As"), 0, this, + SLOT(slotSelectMimeType()), + parent->actionCollection(), "view_as" ); + + kdDebug(1203) << "created info list view\n"; +} + +KonqInfoListViewWidget::~KonqInfoListViewWidget() +{ + delete m_mtSelector; + delete m_metaInfoJob; +} + +void KonqInfoListViewWidget::slotSelectMimeType() +{ + QString comment = m_mtSelector->currentText(); + + // find the mime type by comment + QMapIterator<QString, KonqILVMimeType> it; + for (it = m_counts.begin(); it!=m_counts.end(); ++it) + { + if ((*it).mimetype->comment() == comment) + { + m_favorite = *it; + createFavoriteColumns(); + rebuildView(); + break; + } + } + +} + +void KonqInfoListViewWidget::createColumns() +{ + if (columns()<1) + { + // we can only create the minimum columns here, because we don't get the + // items, from which we determine the columns yet. + addColumn(i18n("Filename"), m_filenameColumnWidth); + } +} + +void KonqInfoListViewWidget::createFavoriteColumns() +{ + while (columns()>1) + { + kdDebug(1203) << "removing column " << columnText(columns()-1) << endl; + removeColumn(columns()-1); + } + + // we need to get the preferred keys of the favorite + const KFileMimeTypeInfo* mimeTypeInfo; + + if (m_favorite.mimetype && + (mimeTypeInfo = KFileMetaInfoProvider::self() + ->mimeTypeInfo(m_favorite.mimetype->name()))) + { + QStringList preferredCols = mimeTypeInfo->preferredKeys(); + m_columnKeys.clear(); //We create the columnKeys as we're creating + //the actual columns, to make sure they're synced + + // get the translations + QStringList groups = mimeTypeInfo->preferredGroups(); + if (groups.isEmpty()) groups = mimeTypeInfo->supportedGroups(); + + QStringList::Iterator prefKey = preferredCols.begin(); + for (; prefKey != preferredCols.end(); ++prefKey) + { + QStringList::Iterator group = groups.begin(); + for (; group != groups.end(); ++group) + { + const KFileMimeTypeInfo::GroupInfo* groupInfo = + mimeTypeInfo->groupInfo(*group); + if(groupInfo) + { + QStringList keys = groupInfo->supportedKeys(); + QStringList::Iterator key = keys.begin(); + for (; key != keys.end(); ++key) + { + if ( *key == *prefKey ) + { + const KFileMimeTypeInfo::ItemInfo* itemInfo = + groupInfo->itemInfo(*key); + addColumn(itemInfo->translatedKey()); + m_columnKeys.append(*key); + } + } + } + } + } + } + else + { + KonqBaseListViewWidget::createColumns(); + } + +} + +bool KonqInfoListViewWidget::openURL( const KURL &url ) +{ + bool ret = KonqBaseListViewWidget::openURL(url); + m_bTopLevelComplete = true; + return ret; +} + +void KonqInfoListViewWidget::rebuildView() +{ + // make a KFileItemList from all our Items + KFileItemList list; + + QListViewItemIterator it(this); + for (; it.current(); ++it) + { + list.append(static_cast<KonqInfoListViewItem*>(it.current())->item()); + } + + // now we can remove all the listview items + clear(); + + // and rebuild them + for (QPtrListIterator<KFileItem> kit(list); kit.current(); ++kit) + { + KonqInfoListViewItem* tmp = new KonqInfoListViewItem( this, *kit ); +// if (m_goToFirstItem==false) +// if (m_itemFound==false) +// if (tmp->text(0)==m_itemToGoTo) +// { +//kdDebug() << "Line " << __LINE__ << endl; +// setCurrentItem(tmp); +//kdDebug() << "Line " << __LINE__ << endl; +// ensureItemVisible(tmp); +//kdDebug() << "Line " << __LINE__ << endl; +// emit selectionChanged(); + //selectCurrentItemAndEnableSelectedBySimpleMoveMode(); +// m_itemFound=true; +//kdDebug() << "Line " << __LINE__ << endl; +// }; + + tmp->gotMetaInfo(); + } + + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } +} + +void KonqInfoListViewWidget::slotNewItems( const KFileItemList& list) +{ + slotStarted(); // ############# WHY? + for (QPtrListIterator<KFileItem> kit ( list ); kit.current(); ++kit ) + { + KonqInfoListViewItem * tmp = new KonqInfoListViewItem( this, *kit ); + + if (!m_itemFound && tmp->text(0)==m_itemToGoTo) + { + setCurrentItem(tmp); + m_itemFound=true; + } + + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( tmp, true ); + } + } + + if ( !(*kit)->isMimeTypeKnown() ) + m_pBrowserView->lstPendingMimeIconItems().append( tmp ); + } + m_pBrowserView->newItems( list ); + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + + slotUpdateBackground(); + + if ( !m_favorite.mimetype ) + determineCounts(list); + + kdDebug(1203) << " ------------------------ startin metainfo job ------\n"; + + // start getting metainfo from the files + if (m_metaInfoJob) + { + for (QPtrListIterator<KFileItem> kit ( list ); kit.current(); ++kit ) + m_metaInfoTodo.append(kit.current()); + } + else + { + m_metaInfoJob = KIO::fileMetaInfo(list); + connect( m_metaInfoJob, SIGNAL( gotMetaInfo( const KFileItem*)), + this, SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, SIGNAL( result( KIO::Job*)), + this, SLOT( slotMetaInfoResult())); + } +} + +void KonqInfoListViewWidget::slotRefreshItems( const KFileItemList& list) +{ + kdDebug(1203) << " ------------------------ startin metainfo job ------\n"; + + // start getting metainfo from the files + if (m_metaInfoJob) + { + for (QPtrListIterator<KFileItem> kit ( list ); kit.current(); ++kit ) + m_metaInfoTodo.append(kit.current()); + } + else + { + m_metaInfoJob = KIO::fileMetaInfo(list); + connect( m_metaInfoJob, SIGNAL( gotMetaInfo( const KFileItem*)), + this, SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, SIGNAL( result( KIO::Job*)), + this, SLOT( slotMetaInfoResult())); + } + KonqBaseListViewWidget::slotRefreshItems(list); +} + +void KonqInfoListViewWidget::slotDeleteItem( KFileItem * item ) +{ + m_metaInfoTodo.removeRef(item); + if (m_metaInfoJob) + m_metaInfoJob->removeItem(item); + + KonqBaseListViewWidget::slotDeleteItem(item); +} + +void KonqInfoListViewWidget::slotClear() +{ + m_metaInfoTodo.clear(); + delete m_metaInfoJob; + m_metaInfoJob = 0; + m_favorite = KonqILVMimeType(); + + KonqBaseListViewWidget::slotClear(); +} + +void KonqInfoListViewWidget::slotMetaInfo(const KFileItem* item) +{ + // need to search for the item (any better way?) + QListViewItemIterator it(this); + for (; it.current(); ++it) + { + if (static_cast<KonqInfoListViewItem*>(it.current())->item()==item) + { + static_cast<KonqInfoListViewItem*>(it.current())->gotMetaInfo(); + return; + } + } + + // we should never reach this place + Q_ASSERT(false); +} + +void KonqInfoListViewWidget::slotMetaInfoResult() +{ + m_metaInfoJob = 0; + if (m_metaInfoTodo.isEmpty()) + { + m_bTopLevelComplete = false; + kdDebug(1203) << "emitting completed!!!!!!!!!!!!!!!!\n"; + slotCompleted(); + } + else + { + m_metaInfoJob = KIO::fileMetaInfo(m_metaInfoTodo); + connect( m_metaInfoJob, SIGNAL( gotMetaInfo( const KFileItem*)), + this, SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, SIGNAL( result( KIO::Job*)), + this, SLOT( slotMetaInfoResult())); + m_metaInfoTodo.clear(); + } +} + +void KonqInfoListViewWidget::determineCounts(const KFileItemList& list) +{ + m_counts.clear(); + m_favorite = KonqILVMimeType(); + // get the counts + for (KFileItemListIterator it(list); it.current(); ++it) + { + QString mt = it.current()->mimetype(); + m_counts[mt].count++; + if (!m_counts[mt].mimetype) + m_counts[mt].mimetype = it.current()->determineMimeType(); + } + + // and look for the plugins + kdDebug(1203) << "counts are:\n"; + + KFileMetaInfoProvider* prov = KFileMetaInfoProvider::self(); + + QStringList mtlist; + + QMapIterator<QString, KonqILVMimeType> it; + for (it = m_counts.begin(); it!=m_counts.end(); ++it) + { + // look if there is a plugin for this mimetype + // and look for the "favorite" mimetype +#ifdef _GNUC +#warning ### change this +#endif + // this will load the plugin which we don't need because we delegate + // the job to the kioslave + (*it).hasPlugin = prov->plugin(it.key()); + + if ( (*it).hasPlugin) + { + mtlist << (*it).mimetype->comment(); + if (m_favorite.count <= (*it).count) + m_favorite = *it; + } + + kdDebug(1203) << it.key() << " -> " << (*it).count + << " item(s) / plugin: " + << ((*it).hasPlugin ? "yes" : "no ") << endl; + } + + m_mtSelector->setItems(mtlist); +// QPopupMenu* menu = m_mtSelector->popupMenu(); + + // insert the icons +// for (int i=0; i<menu->count(); ++i) +// { +// menu->changeItem(i, QIconSet(blah)); +// } + + if (m_favorite.mimetype) + { + m_mtSelector->setCurrentItem(mtlist.findIndex(m_favorite.mimetype->comment())); + kdDebug(1203) << "favorite mimetype is " << m_favorite.mimetype->name() << endl; + } + createFavoriteColumns(); +} + diff --git a/konqueror/listview/konq_infolistviewwidget.h b/konqueror/listview/konq_infolistviewwidget.h new file mode 100644 index 000000000..9d866dc1f --- /dev/null +++ b/konqueror/listview/konq_infolistviewwidget.h @@ -0,0 +1,89 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus <[email protected]> + + 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 version 2.0 + + 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 __KONQ_INFOLISTVIEWWIDGET_H__ +#define __KONQ_INFOLISTVIEWWIDGET_H__ + +#include "konq_listviewwidget.h" + +#include <kurl.h> +#include <qmap.h> +#include <qpair.h> + +namespace KIO {class MetaInfoJob;} +class KonqListView; +class KSelectAction; + +/** + * The info list view + */ +class KonqInfoListViewWidget : public KonqBaseListViewWidget +{ +// friend class KonqTextViewItem; + Q_OBJECT + public: + KonqInfoListViewWidget( KonqListView *parent, QWidget *parentWidget ); + ~KonqInfoListViewWidget(); + + const QStringList columnKeys() {return m_columnKeys;} + + virtual bool openURL( const KURL &url ); + + protected slots: + // slots connected to the directory lister +// virtual void setComplete(); + virtual void slotNewItems( const KFileItemList & ); + virtual void slotRefreshItems( const KFileItemList & ); + virtual void slotDeleteItem( KFileItem * ); + virtual void slotClear(); + virtual void slotSelectMimeType(); + + void slotMetaInfo(const KFileItem*); + void slotMetaInfoResult(); + + protected: + void determineCounts(const KFileItemList& list); + void rebuildView(); + + virtual void createColumns(); + void createFavoriteColumns(); + + /** + * @internal + */ + struct KonqILVMimeType + { + KonqILVMimeType() : mimetype(0), count(0), hasPlugin(false) {}; + + KMimeType::Ptr mimetype; + int count; + bool hasPlugin; + }; + + // all the mimetypes + QMap<QString, KonqILVMimeType > m_counts; + QStringList m_columnKeys; + + KonqILVMimeType m_favorite; + + KSelectAction* m_mtSelector; + KIO::MetaInfoJob* m_metaInfoJob; + KFileItemList m_metaInfoTodo; +}; + +#endif diff --git a/konqueror/listview/konq_listview.cc b/konqueror/listview/konq_listview.cc new file mode 100644 index 000000000..1e67fce36 --- /dev/null +++ b/konqueror/listview/konq_listview.cc @@ -0,0 +1,691 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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_listview.h" +#include "konq_textviewwidget.h" +#include "konq_treeviewwidget.h" +#include "konq_infolistviewwidget.h" +#include "konq_listviewsettings.h" + +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kdirlister.h> +#include <kinputdialog.h> +#include <klocale.h> +#include <konq_drag.h> +#include <kpropertiesdialog.h> +#include <kstdaction.h> +#include <kprotocolinfo.h> +#include <klineedit.h> +#include <kmimetype.h> + +#include <qapplication.h> +#include <qclipboard.h> +#include <qheader.h> +#include <qregexp.h> + +#include <assert.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> +#include <kinstance.h> + +KonqListViewFactory::KonqListViewFactory() +{ + s_instance = 0; + s_defaultViewProps = 0; +} + +KonqListViewFactory::~KonqListViewFactory() +{ + delete s_instance; + delete s_defaultViewProps; + + s_instance = 0; + s_defaultViewProps = 0; +} + +KParts::Part* KonqListViewFactory::createPartObject( QWidget *parentWidget, const char *, QObject *parent, const char *name, const char*, const QStringList &args ) +{ + if( args.count() < 1 ) + kdWarning() << "KonqListView: Missing Parameter" << endl; + + KParts::Part *obj = new KonqListView( parentWidget, parent, name, args.first() ); + return obj; +} + +KInstance *KonqListViewFactory::instance() +{ + if ( !s_instance ) + s_instance = new KInstance( "konqlistview" ); + return s_instance; +} + +KonqPropsView *KonqListViewFactory::defaultViewProps() +{ + if ( !s_defaultViewProps ) + s_defaultViewProps = new KonqPropsView( instance(),0L ); + //s_defaultViewProps = KonqPropsView::defaultProps( instance() ); + + return s_defaultViewProps; +} + +KInstance *KonqListViewFactory::s_instance = 0; +KonqPropsView *KonqListViewFactory::s_defaultViewProps = 0; + +K_EXPORT_COMPONENT_FACTORY( konq_listview, KonqListViewFactory ) + +ListViewBrowserExtension::ListViewBrowserExtension( KonqListView *listView ) + : KonqDirPartBrowserExtension( listView ) +{ + m_listView = listView; +} + +int ListViewBrowserExtension::xOffset() +{ + //kdDebug(1202) << k_funcinfo << endl; + return m_listView->listViewWidget()->contentsX(); +} + +int ListViewBrowserExtension::yOffset() +{ + //kdDebug(1202) << k_funcinfo << endl; + return m_listView->listViewWidget()->contentsY(); +} + +void ListViewBrowserExtension::updateActions() +{ + // This code is very related to KonqIconViewWidget::slotSelectionChanged + int canCopy = 0; + int canDel = 0; + int canTrash = 0; + bool bInTrash = false; + KFileItemList lstItems = m_listView->selectedFileItems(); + + for (KFileItem *item = lstItems.first(); item; item = lstItems.next()) + { + canCopy++; + KURL url = item->url(); + if ( url.directory(false) == KGlobalSettings::trashPath() ) + bInTrash = true; + if ( KProtocolInfo::supportsDeleting( url ) ) + canDel++; + if ( !item->localPath().isEmpty() ) + canTrash++; + } + + emit enableAction( "copy", canCopy > 0 ); + emit enableAction( "cut", canDel > 0 ); + emit enableAction( "trash", canDel > 0 && !bInTrash && canDel == canTrash ); + emit enableAction( "del", canDel > 0 ); + emit enableAction( "properties", lstItems.count() > 0 && KPropertiesDialog::canDisplay( lstItems ) ); + emit enableAction( "editMimeType", ( lstItems.count() == 1 ) ); + emit enableAction( "rename", ( m_listView->listViewWidget()->currentItem() != 0 )&& !bInTrash ); +} + +void ListViewBrowserExtension::copySelection( bool move ) +{ + KonqDrag *urlData = new KonqDrag( m_listView->listViewWidget()->selectedUrls(false), m_listView->listViewWidget()->selectedUrls(true), move ); + QApplication::clipboard()->setData( urlData ); +} + +void ListViewBrowserExtension::paste() +{ + KonqOperations::doPaste( m_listView->listViewWidget(), m_listView->url() ); +} + +void ListViewBrowserExtension::pasteTo( const KURL& url ) +{ + KonqOperations::doPaste( m_listView->listViewWidget(), url ); +} + +void ListViewBrowserExtension::rename() +{ + QListViewItem* item = m_listView->listViewWidget()->currentItem(); + Q_ASSERT ( item ); + m_listView->listViewWidget()->rename( item, 0 ); + + // Enhanced rename: Don't highlight the file extension. + KLineEdit* le = m_listView->listViewWidget()->renameLineEdit(); + if ( le ) { + const QString txt = le->text(); + QString pattern; + KMimeType::diagnoseFileName( txt, pattern ); + if (!pattern.isEmpty() && pattern.at(0)=='*' && pattern.find('*',1)==-1) + le->setSelection(0, txt.length()-pattern.stripWhiteSpace().length()+1); + else + { + int lastDot = txt.findRev('.'); + if (lastDot > 0) + le->setSelection(0, lastDot); + } + } +} + +void ListViewBrowserExtension::trash() +{ + KonqOperations::del(m_listView->listViewWidget(), + KonqOperations::TRASH, + m_listView->listViewWidget()->selectedUrls( true )); +} + +void ListViewBrowserExtension::reparseConfiguration() +{ + // m_pProps is a problem here (what is local, what is global ?) + // but settings is easy : + m_listView->listViewWidget()->initConfig(); +} + +void ListViewBrowserExtension::setSaveViewPropertiesLocally(bool value) +{ + m_listView->props()->setSaveViewPropertiesLocally( value ); +} + +void ListViewBrowserExtension::setNameFilter( const QString &nameFilter ) +{ + m_listView->setNameFilter( nameFilter ); +} + +void ListViewBrowserExtension::properties() +{ + (void) new KPropertiesDialog( m_listView->selectedFileItems() ); +} + +void ListViewBrowserExtension::editMimeType() +{ + KFileItemList items = m_listView->selectedFileItems(); + assert ( items.count() == 1 ); + KonqOperations::editMimeType( items.first()->mimetype() ); +} + +KonqListView::KonqListView( QWidget *parentWidget, QObject *parent, const char *name, const QString& mode ) + : KonqDirPart( parent, name ) +,m_headerTimer(0) +{ + setInstance( KonqListViewFactory::instance(), false ); + + // Create a properties instance for this view + // All the listview view modes inherit the same properties defaults... + m_pProps = new KonqPropsView( KonqListViewFactory::instance(), KonqListViewFactory::defaultViewProps() ); + + setBrowserExtension( new ListViewBrowserExtension( this ) ); + + QString xmlFile; + + if (mode=="TextView") + { + kdDebug(1202) << "Creating KonqTextViewWidget" << endl; + xmlFile = "konq_textview.rc"; + m_pListView=new KonqTextViewWidget(this, parentWidget); + } + else if (mode=="MixedTree") + { + kdDebug(1202) << "Creating KonqTreeViewWidget" << endl; + xmlFile = "konq_treeview.rc"; + m_pListView=new KonqTreeViewWidget(this,parentWidget); + } + else if (mode=="InfoListView") + { + kdDebug(1202) << "Creating KonqInfoListViewWidget" << endl; + xmlFile = "konq_infolistview.rc"; + m_pListView=new KonqInfoListViewWidget(this,parentWidget); + } + else + { + kdDebug(1202) << "Creating KonqDetailedListViewWidget" << endl; + xmlFile = "konq_detailedlistview.rc"; + m_pListView = new KonqBaseListViewWidget( this, parentWidget); + } + setWidget( m_pListView ); + setDirLister( m_pListView->m_dirLister ); + + m_mimeTypeResolver = new KMimeTypeResolver<KonqBaseListViewItem,KonqListView>(this); + + setXMLFile( xmlFile ); + + setupActions(); + + m_pListView->confColumns.resize( 11 ); + m_pListView->confColumns[0].setData(I18N_NOOP("MimeType"),"Type",KIO::UDS_MIME_TYPE,m_paShowMimeType); + m_pListView->confColumns[1].setData(I18N_NOOP("Size"),"Size",KIO::UDS_SIZE,m_paShowSize); + m_pListView->confColumns[2].setData(I18N_NOOP("Modified"),"Date",KIO::UDS_MODIFICATION_TIME,m_paShowTime); + m_pListView->confColumns[3].setData(I18N_NOOP("Accessed"),"AccessDate",KIO::UDS_ACCESS_TIME,m_paShowAccessTime); + m_pListView->confColumns[4].setData(I18N_NOOP("Created"),"CreationDate",KIO::UDS_CREATION_TIME,m_paShowCreateTime); + m_pListView->confColumns[5].setData(I18N_NOOP("Permissions"),"Access",KIO::UDS_ACCESS,m_paShowPermissions); + m_pListView->confColumns[6].setData(I18N_NOOP("Owner"),"Owner",KIO::UDS_USER,m_paShowOwner); + m_pListView->confColumns[7].setData(I18N_NOOP("Group"),"Group",KIO::UDS_GROUP,m_paShowGroup); + m_pListView->confColumns[8].setData(I18N_NOOP("Link"),"Link",KIO::UDS_LINK_DEST,m_paShowLinkDest); + m_pListView->confColumns[9].setData(I18N_NOOP("URL"),"URL",KIO::UDS_URL,m_paShowURL); + // Note: File Type is in fact the mimetype comment. We use UDS_FILE_TYPE but that's not what we show in fact :/ + m_pListView->confColumns[10].setData(I18N_NOOP("File Type"),"Type",KIO::UDS_FILE_TYPE,m_paShowType); + + + connect( m_pListView, SIGNAL( selectionChanged() ), + m_extension, SLOT( updateActions() ) ); + connect( m_pListView, SIGNAL( selectionChanged() ), + this, SLOT( slotSelectionChanged() ) ); + + connect( m_pListView, SIGNAL( currentChanged(QListViewItem*) ), + m_extension, SLOT( updateActions() ) ); + connect(m_pListView->header(),SIGNAL(indexChange(int,int,int)),this,SLOT(headerDragged(int,int,int))); + connect(m_pListView->header(),SIGNAL(clicked(int)),this,SLOT(slotHeaderClicked(int))); + connect(m_pListView->header(),SIGNAL(sizeChange(int,int,int)),SLOT(slotHeaderSizeChanged())); + + // signals from konqdirpart (for BC reasons) + connect( this, SIGNAL( findOpened( KonqDirPart * ) ), SLOT( slotKFindOpened() ) ); + connect( this, SIGNAL( findClosed( KonqDirPart * ) ), SLOT( slotKFindClosed() ) ); + + loadPlugins( this, this, instance() ); +} + +KonqListView::~KonqListView() +{ + delete m_mimeTypeResolver; + delete m_pProps; +} + +void KonqListView::guiActivateEvent( KParts::GUIActivateEvent *event ) +{ + KonqDirPart::guiActivateEvent(event ); + //ReadOnlyPart::guiActivateEvent(event ); + ((ListViewBrowserExtension*)m_extension)->updateActions(); +} + +bool KonqListView::doOpenURL( const KURL &url ) +{ + KURL u( url ); + const QString prettyURL = url.pathOrURL(); + emit setWindowCaption( prettyURL ); + return m_pListView->openURL( url ); +} + +bool KonqListView::doCloseURL() +{ + m_pListView->stop(); + m_mimeTypeResolver->m_lstPendingMimeIconItems.clear(); + return true; +} + +void KonqListView::listingComplete() +{ + m_mimeTypeResolver->start( /*10*/ 0 ); +} + +void KonqListView::determineIcon( KonqBaseListViewItem * item ) +{ + //int oldSerial = item->pixmap(0)->serialNumber(); + + (void) item->item()->determineMimeType(); + + //QPixmap newIcon = item->item()->pixmap( m_parent->iconSize(), + // item->state() ); + //if ( oldSerial != newIcon.serialNumber() ) + // item->setPixmap( 0, newIcon ); + + // We also have columns to update, not only the icon + item->updateContents(); +} + +void KonqListView::saveState( QDataStream &stream ) +{ + //kdDebug(1202) << k_funcinfo << endl; + KonqDirPart::saveState( stream ); + m_pListView->saveState( stream ); +} + +void KonqListView::restoreState( QDataStream &stream ) +{ + //kdDebug(1202) << k_funcinfo << endl; + KonqDirPart::restoreState( stream ); + m_pListView->restoreState( stream ); +} + +void KonqListView::disableIcons( const KURL::List &lst ) +{ + m_pListView->disableIcons( lst ); +} + +void KonqListView::slotSelect() +{ + bool ok; + QString pattern = KInputDialog::getText( QString::null, + i18n( "Select files:" ), "*", &ok, m_pListView ); + if ( !ok ) + return; + + QRegExp re( pattern, true, true ); + + m_pListView->blockSignals( true ); + + for (KonqBaseListViewWidget::iterator it = m_pListView->begin(); it != m_pListView->end(); it++ ) + { + if ((m_pListView->automaticSelection()) && (it->isSelected())) + { + it->setSelected(FALSE); + //the following line is to prevent that more than one item were selected + //and now get deselected and automaticSelection() was true, this shouldn't happen + //but who knows, aleXXX + m_pListView->deactivateAutomaticSelection(); + }; + if ( re.exactMatch( it->text(0) ) ) + it->setSelected( TRUE); + }; + m_pListView->blockSignals( false ); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); + m_pListView->viewport()->update(); +} + +void KonqListView::slotUnselect() +{ + bool ok; + QString pattern = KInputDialog::getText( QString::null, + i18n( "Unselect files:" ), "*", &ok, m_pListView ); + if ( !ok ) + return; + + QRegExp re( pattern, TRUE, TRUE ); + + m_pListView->blockSignals(TRUE); + + for (KonqBaseListViewWidget::iterator it = m_pListView->begin(); it != m_pListView->end(); it++ ) + if ( re.exactMatch( it->text(0) ) ) + it->setSelected(FALSE); + + m_pListView->blockSignals(FALSE); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); + m_pListView->viewport()->update(); +} + +void KonqListView::slotSelectAll() +{ + m_pListView->selectAll(TRUE); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); +} + +void KonqListView::slotUnselectAll() +{ + m_pListView->selectAll(FALSE); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); +} + + +void KonqListView::slotInvertSelection() +{ + if ((m_pListView->automaticSelection()) + && (m_pListView->currentItem()!=0) + && (m_pListView->currentItem()->isSelected())) + m_pListView->currentItem()->setSelected(FALSE); + + m_pListView->invertSelection(); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); + m_pListView->viewport()->update(); +} + +void KonqListView::newIconSize( int size ) +{ + KonqDirPart::newIconSize( size ); + m_pListView->updateListContents(); +} + +void KonqListView::slotShowDot() +{ + m_pProps->setShowingDotFiles( m_paShowDot->isChecked() ); + m_pListView->m_dirLister->setShowingDotFiles( m_pProps->isShowingDotFiles() ); + m_pListView->m_dirLister->emitChanges(); +} + +void KonqListView::slotCaseInsensitive() +{ + m_pProps->setCaseInsensitiveSort( m_paCaseInsensitive->isChecked() ); + m_pListView->sort(); +} + +void KonqListView::slotColumnToggled() +{ + kdDebug(1202) << "::slotColumnToggled" << endl; + for (uint i=0; i<m_pListView->NumberOfAtoms; i++) + { + m_pListView->confColumns[i].displayThisOne=!m_pListView->confColumns[i].toggleThisOne + || (m_pListView->confColumns[i].toggleThisOne->isChecked()&&m_pListView->confColumns[i].toggleThisOne->isEnabled()); + //this column has been enabled, the columns after it slide one column back + if ((m_pListView->confColumns[i].displayThisOne) && (m_pListView->confColumns[i].displayInColumn==-1)) + { + int maxColumn(0); + for (uint j=0; j<m_pListView->NumberOfAtoms; j++) + if ((m_pListView->confColumns[j].displayInColumn>maxColumn) && (m_pListView->confColumns[j].displayThisOne)) + maxColumn=m_pListView->confColumns[j].displayInColumn; + m_pListView->confColumns[i].displayInColumn=maxColumn+1; + } + //this column has been disabled, the columns after it slide one column + if ((!m_pListView->confColumns[i].displayThisOne) && (m_pListView->confColumns[i].displayInColumn!=-1)) + { + for (uint j=0; j<m_pListView->NumberOfAtoms; j++) + if (m_pListView->confColumns[j].displayInColumn>m_pListView->confColumns[i].displayInColumn) + m_pListView->confColumns[j].displayInColumn--; + m_pListView->confColumns[i].displayInColumn=-1; + } + } + + //create the new list contents + m_pListView->createColumns(); + m_pListView->updateListContents(); + + //save the config + QStringList lstColumns; + int currentColumn(m_pListView->m_filenameColumn+1); + for (int i=0; i<(int)m_pListView->NumberOfAtoms; i++) + { + kdDebug(1202)<<"checking: -"<<m_pListView->confColumns[i].name<<"-"<<endl; + if ((m_pListView->confColumns[i].displayThisOne) && (currentColumn==m_pListView->confColumns[i].displayInColumn)) + { + lstColumns.append(m_pListView->confColumns[i].name); + kdDebug(1202)<<" adding"<<endl; + currentColumn++; + i=-1; + } + } + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setColumns( lstColumns ); + config.writeConfig(); + + // Update column sizes + slotHeaderSizeChanged(); +} + +void KonqListView::slotHeaderClicked(int sec) +{ + kdDebug(1202)<<"section: "<<sec<<" clicked"<<endl; + int clickedColumn(-1); + for (uint i=0; i<m_pListView->NumberOfAtoms; i++) + if (m_pListView->confColumns[i].displayInColumn==sec) clickedColumn=i; + kdDebug(1202)<<"atom index "<<clickedColumn<<endl; + QString nameOfSortColumn; + //we clicked the file name column + if (clickedColumn==-1) + nameOfSortColumn="FileName"; + else + nameOfSortColumn=m_pListView->confColumns[clickedColumn].desktopFileName; + + if (nameOfSortColumn!=m_pListView->sortedByColumn) + { + m_pListView->sortedByColumn=nameOfSortColumn; + m_pListView->setAscending(TRUE); + } + else + m_pListView->setAscending(!m_pListView->ascending()); + + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setSortBy( nameOfSortColumn ); + config.setSortOrder( m_pListView->ascending() ); + config.writeConfig(); +} + +void KonqListView::headerDragged(int sec, int from, int to) +{ + kdDebug(1202)<<"section: "<<sec<<" fromIndex: "<<from<<" toIndex "<<to<<endl; + //at this point the columns aren't moved yet, so I let the listview + //rearrange the stuff and use a single shot timer + QTimer::singleShot(200,this,SLOT(slotSaveAfterHeaderDrag())); +} + +const KFileItem * KonqListView::currentItem() +{ + if (m_pListView==0 || m_pListView->currentItem()==0) + return 0L; + return static_cast<KonqListViewItem *>(m_pListView->currentItem())->item(); +} + +void KonqListView::slotSaveAfterHeaderDrag() +{ + QStringList lstColumns; + + for ( int i=0; i < m_pListView->columns(); i++ ) + { + int section = m_pListView->header()->mapToSection( i ); + + // look for section + for ( uint j=0; j < m_pListView->NumberOfAtoms; j++ ) + { + if ( m_pListView->confColumns[j].displayInColumn == section ) + { + lstColumns.append( m_pListView->confColumns[j].name ); + break; + } + } + } + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setColumns( lstColumns ); + config.writeConfig(); + + // Update column sizes + slotHeaderSizeChanged(); +} + +void KonqListView::slotSaveColumnWidths() +{ + QValueList<int> lstColumnWidths; + + for ( int i=0; i < m_pListView->columns(); i++ ) + { + int section = m_pListView->header()->mapToSection( i ); + + // look for section + for ( uint j=0; j < m_pListView->NumberOfAtoms; j++ ) + { + // Save size only if the column is found + if ( m_pListView->confColumns[j].displayInColumn == section ) + { + m_pListView->confColumns[j].width = m_pListView->columnWidth(section); + lstColumnWidths.append( m_pListView->confColumns[j].width ); + break; + } + } + } + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setColumnWidths( lstColumnWidths ); + + // size of current filename column + config.setFileNameColumnWidth( m_pListView->columnWidth(0) ); + config.writeConfig(); +} + +void KonqListView::slotHeaderSizeChanged() +{ + if ( !m_headerTimer ) + { + m_headerTimer = new QTimer( this ); + connect( m_headerTimer, SIGNAL( timeout() ), this, SLOT( slotSaveColumnWidths() ) ); + } + else + m_headerTimer->stop(); + + m_headerTimer->start( 250, true ); +} + +void KonqListView::slotKFindOpened() +{ + if ( m_pListView->m_dirLister ) + m_pListView->m_dirLister->setAutoUpdate( false ); +} + +void KonqListView::slotKFindClosed() +{ + if ( m_pListView->m_dirLister ) + m_pListView->m_dirLister->setAutoUpdate( true ); +} + +void KonqListView::setupActions() +{ + m_paShowTime=new KToggleAction(i18n("Show &Modification Time"), 0,this, SLOT(slotColumnToggled()), actionCollection(), "show_time" ); + m_paShowTime->setCheckedState(i18n("Hide &Modification Time")); + m_paShowType=new KToggleAction(i18n("Show &File Type"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_type" ); + m_paShowType->setCheckedState(i18n("Hide &File Type")); + m_paShowMimeType=new KToggleAction(i18n("Show MimeType"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_mimetype" ); + m_paShowMimeType->setCheckedState(i18n("Hide MimeType")); + m_paShowAccessTime=new KToggleAction(i18n("Show &Access Time"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_access_time" ); + m_paShowAccessTime->setCheckedState(i18n("Hide &Access Time")); + m_paShowCreateTime=new KToggleAction(i18n("Show &Creation Time"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_creation_time" ); + m_paShowCreateTime->setCheckedState(i18n("Hide &Creation Time")); + m_paShowLinkDest=new KToggleAction(i18n("Show &Link Destination"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_link_dest" ); + m_paShowLinkDest->setCheckedState(i18n("Hide &Link Destination")); + m_paShowSize=new KToggleAction(i18n("Show Filesize"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_size" ); + m_paShowSize->setCheckedState(i18n("Hide Filesize")); + m_paShowOwner=new KToggleAction(i18n("Show Owner"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_owner" ); + m_paShowOwner->setCheckedState(i18n("Hide Owner")); + m_paShowGroup=new KToggleAction(i18n("Show Group"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_group" ); + m_paShowGroup->setCheckedState(i18n("Hide Group")); + m_paShowPermissions=new KToggleAction(i18n("Show Permissions"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_permissions" ); + m_paShowPermissions->setCheckedState(i18n("Hide Permissions")); + m_paShowURL=new KToggleAction(i18n("Show URL"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_url" ); + + 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_paShowDot = new KToggleAction( i18n( "Show &Hidden Files" ), 0, this, SLOT( slotShowDot() ), actionCollection(), "show_dot" ); +// m_paShowDot->setCheckedState(i18n("Hide &Hidden Files")); + m_paCaseInsensitive = new KToggleAction(i18n("Case Insensitive Sort"), 0, this, SLOT(slotCaseInsensitive()),actionCollection(), "sort_caseinsensitive" ); + + newIconSize( KIcon::SizeSmall /* default size */ ); +} + +void KonqListView::slotSelectionChanged() +{ + bool itemSelected = selectedFileItems().count()>0; + m_paUnselect->setEnabled( itemSelected ); + m_paUnselectAll->setEnabled( itemSelected ); +// m_paInvertSelection->setEnabled( itemSelected ); +} + +#include "konq_listview.moc" + + diff --git a/konqueror/listview/konq_listview.h b/konqueror/listview/konq_listview.h new file mode 100644 index 000000000..b149b703c --- /dev/null +++ b/konqueror/listview/konq_listview.h @@ -0,0 +1,210 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 __konq_listview_h__ +#define __konq_listview_h__ + +#include <kparts/browserextension.h> +#include <kglobalsettings.h> +#include <konq_operations.h> +#include <kparts/factory.h> +#include <konq_dirpart.h> +#include <kmimetyperesolver.h> + +#include <qvaluelist.h> +#include <qlistview.h> +#include <qstringlist.h> + +#include <konq_propsview.h> +#include "konq_listviewwidget.h" + +class KAction; +class KToggleAction; +class ListViewBrowserExtension; + +class KonqListViewFactory : public KParts::Factory +{ +public: + KonqListViewFactory(); + virtual ~KonqListViewFactory(); + + virtual KParts::Part* createPartObject( QWidget *parentWidget, const char *, QObject *parent, const char *name, const char*, const QStringList &args ); + + static KInstance *instance(); + static KonqPropsView *defaultViewProps(); + +private: + static KInstance *s_instance; + static KonqPropsView *s_defaultViewProps; +}; + +/** + * The part for the tree view. It does quite nothing, just the + * konqueror interface. Most of the functionality is in the + * widget, KonqListViewWidget. + */ +class KonqListView : public KonqDirPart +{ + friend class KonqBaseListViewWidget; + Q_OBJECT + Q_PROPERTY( bool supportsUndo READ supportsUndo ) +public: + KonqListView( QWidget *parentWidget, QObject *parent, const char *name, const QString& mode ); + virtual ~KonqListView(); + + virtual const KFileItem * currentItem(); + virtual KFileItemList selectedFileItems() {return m_pListView->selectedFileItems();}; + + KonqBaseListViewWidget *listViewWidget() const { return m_pListView; } + + bool supportsUndo() const { return true; } + + virtual void saveState( QDataStream &stream ); + virtual void restoreState( QDataStream &stream ); + + // "Cut" icons : disable those whose URL is in lst, enable the others + virtual void disableIcons( const KURL::List & lst ); + + // See KMimeTypeResolver + void mimeTypeDeterminationFinished() {} + //int iconSize() { return m_pListView->iconSize(); } + void determineIcon( KonqBaseListViewItem * item ); + + QPtrList<KonqBaseListViewItem> & lstPendingMimeIconItems() { return m_mimeTypeResolver->m_lstPendingMimeIconItems; } + void listingComplete(); + + virtual void newIconSize( int ); + +protected: + virtual bool doOpenURL( const KURL &url ); + virtual bool doCloseURL(); + virtual bool openFile() { return true; } + + void setupActions(); + void guiActivateEvent( KParts::GUIActivateEvent *event ); + +protected slots: + void slotSelect(); + void slotUnselect(); + void slotSelectAll(); + void slotUnselectAll(); + void slotInvertSelection(); + void slotCaseInsensitive(); + void slotSelectionChanged(); + + void slotShowDot(); + //this is called if a item in the submenu is toggled + //it saves the new configuration according to the menu items + //and calls createColumns() + //it adjusts the indece of the remaining columns + void slotColumnToggled(); + //this is called when the user changes the order of the + //columns by dragging them + //at this moment the columns haven't changed their order yet, so + //it starts a singleshottimer, after which the columns changed their order + //and then slotSaveAfterHeaderDrag is called + void headerDragged(int sec, int from, int to); + //saves the new order of the columns + void slotSaveAfterHeaderDrag(); + // column width changed + void slotHeaderSizeChanged(); + void slotSaveColumnWidths(); // delayed + void slotHeaderClicked(int sec); + + // This comes from KonqDirPart, it's for the "Find" feature + virtual void slotStarted() { m_pListView->slotStarted(); } + virtual void slotCanceled() { m_pListView->slotCanceled(); } + virtual void slotCompleted() { m_pListView->slotCompleted(); } + virtual void slotNewItems( const KFileItemList& lst ) { m_pListView->slotNewItems( lst ); } + virtual void slotDeleteItem( KFileItem * item ) { m_pListView->slotDeleteItem( item ); } + virtual void slotRefreshItems( const KFileItemList& lst ) { m_pListView->slotRefreshItems( lst ); } + virtual void slotClear() { m_pListView->slotClear(); } + virtual void slotRedirection( const KURL & u ) { m_pListView->slotRedirection( u ); } + + // Connected to KonqDirPart + void slotKFindOpened(); + void slotKFindClosed(); + +private: + + KonqBaseListViewWidget *m_pListView; + KMimeTypeResolver<KonqBaseListViewItem,KonqListView> *m_mimeTypeResolver; + QTimer *m_headerTimer; + + KAction *m_paSelect; + KAction *m_paUnselect; + KAction *m_paSelectAll; + KAction *m_paUnselectAll; + KAction *m_paInvertSelection; + + KToggleAction *m_paCaseInsensitive; + + KToggleAction *m_paShowDot; + KToggleAction *m_paShowTime; + KToggleAction *m_paShowType; + KToggleAction *m_paShowMimeType; + KToggleAction *m_paShowAccessTime; + KToggleAction *m_paShowCreateTime; + KToggleAction *m_paShowLinkDest; + KToggleAction *m_paShowSize; + KToggleAction *m_paShowOwner; + KToggleAction *m_paShowGroup; + KToggleAction *m_paShowPermissions; + KToggleAction *m_paShowURL; +}; + +class ListViewBrowserExtension : public KonqDirPartBrowserExtension +{ + Q_OBJECT + friend class KonqListView; + friend class KonqBaseListViewWidget; + public: + ListViewBrowserExtension( KonqListView *listView ); + + virtual int xOffset(); + virtual int yOffset(); + + protected slots: + void updateActions(); + + void copy() { copySelection( false ); } + void cut() { copySelection( true ); } + void paste(); + void pasteTo( const KURL & ); + void rename(); + void trash(); + void del() { KonqOperations::del(m_listView->listViewWidget(), + KonqOperations::DEL, + m_listView->listViewWidget()->selectedUrls()); } + + void reparseConfiguration(); + void setSaveViewPropertiesLocally( bool value ); + void setNameFilter( const QString &nameFilter ); + // void refreshMimeTypes is missing + + void properties(); + void editMimeType(); + + private: + void copySelection( bool move ); + + KonqListView *m_listView; +}; + +#endif diff --git a/konqueror/listview/konq_listview.kcfg b/konqueror/listview/konq_listview.kcfg new file mode 100644 index 000000000..cd7d2bc68 --- /dev/null +++ b/konqueror/listview/konq_listview.kcfg @@ -0,0 +1,37 @@ +<?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" > + <include>kapplication.h</include> + <kcfgfile name="konquerorrc"> + <parameter name="Protocol" /> + </kcfgfile> + + <group name="ListView_$(Protocol)"> + <entry key="SortBy" type="String"> + <default>FileName</default> + <label>List is sorted by this item</label> + <whatsthis></whatsthis> + </entry> + <entry key="SortOrder" type="Bool"> + <default>true</default> + <label>Sort Order</label> + <whatsthis></whatsthis> + </entry> + <entry key="FileNameColumnWidth" type="Int"> + <default code="true">25 * KApplication::kApplication()->fontMetrics().width( "m" )</default> + <label>Width of the FileName Column</label> + <whatsthis></whatsthis> + </entry> + <entry key="Columns" type="StringList"> + <label>Columns</label> + <whatsthis></whatsthis> + </entry> + <entry key="ColumnWidths" type="IntList"> + <label>Widths of the Columns</label> + <whatsthis></whatsthis> + </entry> + </group> + +</kcfg>
\ No newline at end of file diff --git a/konqueror/listview/konq_listviewitems.cc b/konqueror/listview/konq_listviewitems.cc new file mode 100644 index 000000000..f946856c4 --- /dev/null +++ b/konqueror/listview/konq_listviewitems.cc @@ -0,0 +1,449 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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_listview.h" +#include <konq_settings.h> +#include <kdebug.h> +#include <klocale.h> +#include <assert.h> +#include <stdio.h> +#include <qpainter.h> +#include <qheader.h> +#include <kiconloader.h> + +static QString retrieveExtraEntry( KFileItem* fileitem, int numExtra ) +{ + /// ######## SLOOOOW + KIO::UDSEntry::ConstIterator it = fileitem->entry().begin(); + const KIO::UDSEntry::ConstIterator end = fileitem->entry().end(); + int n = 0; + for( ; it != end; ++it ) + { + if ((*it).m_uds == KIO::UDS_EXTRA) + { + ++n; + if ( n == numExtra ) + { + return (*it).m_str; + } + } + } + return QString::null; +} + + +/************************************************************** + * + * KonqListViewItem + * + **************************************************************/ +KonqListViewItem::KonqListViewItem( KonqBaseListViewWidget *_listViewWidget, + KonqListViewItem * _parent, KFileItem* _fileitem ) + : KonqBaseListViewItem( _listViewWidget, _parent, _fileitem ), + m_pixmaps( listView()->columns() ) +{ + updateContents(); +} + +KonqListViewItem::KonqListViewItem( KonqBaseListViewWidget *_listViewWidget, KFileItem* _fileitem ) + : KonqBaseListViewItem( _listViewWidget, _fileitem ), + m_pixmaps( listView()->columns() ) +{ + updateContents(); +} + +KonqListViewItem::~KonqListViewItem() +{ + for ( QValueVector<QPixmap*>::iterator + it = m_pixmaps.begin(), itEnd = m_pixmaps.end(); + it != itEnd; ++it ) + delete *it; +} + +void KonqListViewItem::updateContents() +{ + // Set the pixmap + setDisabled( m_bDisabled ); + + // Set the text of each column + setText( 0, m_fileitem->text() ); + + // The order is: .dir (0), dir (1), .file (2), file (3) + sortChar = S_ISDIR( m_fileitem->mode() ) ? 1 : 3; + if ( m_fileitem->text()[0] == '.' ) + --sortChar; + + //now we have the first column, so let's do the rest + + int numExtra = 1; + for ( unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms; i++ ) + { + ColumnInfo *tmpColumn=&m_pListViewWidget->columnConfigInfo()[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case KIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case KIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case KIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case KIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case KIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case KIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case KIO::UDS_SIZE: + if ( m_pListViewWidget->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatNumber( m_fileitem->size(),0)+" "); + else + setText(tmpColumn->displayInColumn,KIO::convertSize(m_fileitem->size())+" "); + break; + case KIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + QDateTime dt; + time_t _time = m_fileitem->time( tmpColumn->udsId ); + if ( _time != 0 ) + { + dt.setTime_t( _time ); + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatDateTime(dt)); + } + } + break; + case KIO::UDS_EXTRA: + { + const QString entryStr = retrieveExtraEntry( m_fileitem, numExtra ); + if ( tmpColumn->type == QVariant::DateTime ) + { + QDateTime dt = QDateTime::fromString( entryStr, Qt::ISODate ); + setText(tmpColumn->displayInColumn, + KGlobal::locale()->formatDateTime(dt)); + } + else // if ( tmpColumn->type == QVariant::String ) + setText(tmpColumn->displayInColumn, entryStr); + ++numExtra; + break; + } + default: + break; + }; + }; + }; +} + +void KonqListViewItem::setDisabled( bool disabled ) +{ + KonqBaseListViewItem::setDisabled( disabled ); + int iconSize = m_pListViewWidget->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqListViewItem::setActive( bool active ) +{ + if ( m_bActive == active ) + return; + + //#### Optimize away repaint if possible, like the iconview does? + KonqBaseListViewItem::setActive( active ); + int iconSize = m_pListViewWidget->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqListViewItem::setPixmap( int column, const QPixmap& pm ) +{ + if ( column < 0 ) + return; + + const QPixmap *current = pixmap( column ); + + if ( ( pm.isNull() && !current ) || + ( current && pm.serialNumber() == current->serialNumber() ) ) + return; + + int oldWidth = current ? current->width() : 0; + int oldHeight = current ? current->height() : 0; + + if ( (int)m_pixmaps.size() <= column ) + m_pixmaps.resize( column+1 ); + + delete current; + m_pixmaps[column] = pm.isNull() ? 0 : new QPixmap( pm ); + + int newWidth = pm.isNull() ? 0 : pm.width(); + int newHeight = pm.isNull() ? 0 : pm.height(); + + // If the height or width have changed then we're going to have to repaint + // this whole thing. Fortunately since most of the calls are coming from + // setActive() this is the uncommon case. + + if ( oldWidth != newWidth || oldHeight != newHeight ) + { + setup(); + widthChanged( column ); + invalidateHeight(); + return; + } + + // If we're just replacing the icon with another one its size -- i.e. a + // "highlighted" icon, don't bother repainting the whole widget. + + QListView *lv = m_pListViewWidget; + + int decorationWidth = lv->treeStepSize() * ( depth() + ( lv->rootIsDecorated() ? 1 : 0 ) ); + int x = lv->header()->sectionPos( column ) + decorationWidth + lv->itemMargin(); + int y = lv->itemPos( this ); + int w = newWidth; + int h = height(); + lv->repaintContents( x, y, w, h ); +} + +const QPixmap* KonqListViewItem::pixmap( int column ) const +{ + bool ok; + if ((int)m_pixmaps.count() <= column) + return 0; + + QPixmap *pm = m_pixmaps.at( column, &ok ); + if( !ok ) + return 0; + return pm; +} + +int KonqBaseListViewItem::compare( QListViewItem* item, int col, bool ascending ) const +{ + KonqListViewItem* k = static_cast<KonqListViewItem*>( item ); + if ( sortChar != k->sortChar ) + // Dirs are always first, even when sorting in descending order + return !ascending ? k->sortChar - sortChar : sortChar - k->sortChar; + + int numExtra = 0; + for ( unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms; i++ ) + { + ColumnInfo *cInfo = &m_pListViewWidget->columnConfigInfo()[i]; + if ( cInfo->udsId == KIO::UDS_EXTRA ) + ++numExtra; + if ( col == cInfo->displayInColumn ) + { + switch ( cInfo->udsId ) + { + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + time_t t1 = m_fileitem->time( cInfo->udsId ); + time_t t2 = k->m_fileitem->time( cInfo->udsId ); + return ( t1 > t2 ) ? 1 : ( t1 < t2 ) ? -1 : 0; + } + case KIO::UDS_SIZE: + { + KIO::filesize_t s1 = m_fileitem->size(); + KIO::filesize_t s2 = k->m_fileitem->size(); + return ( s1 > s2 ) ? 1 : ( s1 < s2 ) ? -1 : 0; + } + case KIO::UDS_EXTRA: + { + if ( cInfo->type & QVariant::DateTime ) { + const QString entryStr1 = retrieveExtraEntry( m_fileitem, numExtra ); + QDateTime dt1 = QDateTime::fromString( entryStr1, Qt::ISODate ); + const QString entryStr2 = retrieveExtraEntry( k->m_fileitem, numExtra ); + QDateTime dt2 = QDateTime::fromString( entryStr2, Qt::ISODate ); + return ( dt1 > dt2 ) ? 1 : ( dt1 < dt2 ) ? -1 : 0; + } + } + default: + break; + } + break; + } + } + if ( m_pListViewWidget->caseInsensitiveSort() ) + return text( col ).lower().localeAwareCompare( k->text( col ).lower() ); + else { + return m_pListViewWidget->m_pSettings->caseSensitiveCompare( text( col ), k->text( col ) ); + } +} + +void KonqListViewItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + QColorGroup cg( _cg ); + + if ( _column == 0 ) + { + _painter->setFont( m_pListViewWidget->itemFont() ); + } + + cg.setColor( QColorGroup::Text, m_pListViewWidget->itemColor() ); + + KListView *lv = static_cast< KListView* >( listView() ); + const QPixmap *pm = lv->viewport()->paletteBackgroundPixmap(); + if ( _column == 0 && isSelected() && !lv->allColumnsShowFocus() ) + { + int newWidth = width( lv->fontMetrics(), lv, _column ); + if ( newWidth > _width ) + newWidth = _width; + if ( pm && !pm->isNull() ) + { + cg.setBrush( QColorGroup::Base, QBrush( backgroundColor(_column), *pm ) ); + QPoint o = _painter->brushOrigin(); + _painter->setBrushOrigin( o.x() - lv->contentsX(), o.y() - lv->contentsY() ); + const QColorGroup::ColorRole crole = + QPalette::backgroundRoleFromMode( lv->viewport()->backgroundMode() ); + _painter->fillRect( newWidth, 0, _width - newWidth, height(), cg.brush( crole ) ); + _painter->setBrushOrigin( o ); + } + else + { + _painter->fillRect( newWidth, 0, _width - newWidth, height(), backgroundColor(_column) ); + } + + _width = newWidth; + } + + KListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +void KonqListViewItem::paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & _r ) +{ + QRect r( _r ); + QListView *lv = static_cast< QListView * >( listView() ); + r.setWidth( width( lv->fontMetrics(), lv, 0 ) ); + if ( r.right() > lv->header()->sectionRect( 0 ).right() ) + r.setRight( lv->header()->sectionRect( 0 ).right() ); + QListViewItem::paintFocus( _painter, cg, r ); +} + +const char* KonqBaseListViewItem::makeAccessString( const mode_t mode) +{ + static char buffer[ 12 ]; + + char uxbit,gxbit,oxbit; + + if ( (mode & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) ) + uxbit = 's'; + else if ( (mode & (S_IXUSR|S_ISUID)) == S_ISUID ) + uxbit = 'S'; + else if ( (mode & (S_IXUSR|S_ISUID)) == S_IXUSR ) + uxbit = 'x'; + else + uxbit = '-'; + + if ( (mode & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) ) + gxbit = 's'; + else if ( (mode & (S_IXGRP|S_ISGID)) == S_ISGID ) + gxbit = 'S'; + else if ( (mode & (S_IXGRP|S_ISGID)) == S_IXGRP ) + gxbit = 'x'; + else + gxbit = '-'; + + if ( (mode & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) ) + oxbit = 't'; + else if ( (mode & (S_IXOTH|S_ISVTX)) == S_ISVTX ) + oxbit = 'T'; + else if ( (mode & (S_IXOTH|S_ISVTX)) == S_IXOTH ) + oxbit = 'x'; + else + oxbit = '-'; + + buffer[0] = ((( mode & S_IRUSR ) == S_IRUSR ) ? 'r' : '-' ); + buffer[1] = ((( mode & S_IWUSR ) == S_IWUSR ) ? 'w' : '-' ); + buffer[2] = uxbit; + buffer[3] = ((( mode & S_IRGRP ) == S_IRGRP ) ? 'r' : '-' ); + buffer[4] = ((( mode & S_IWGRP ) == S_IWGRP ) ? 'w' : '-' ); + buffer[5] = gxbit; + buffer[6] = ((( mode & S_IROTH ) == S_IROTH ) ? 'r' : '-' ); + buffer[7] = ((( mode & S_IWOTH ) == S_IWOTH ) ? 'w' : '-' ); + buffer[8] = oxbit; + buffer[9] = 0; + + return buffer; +} + +KonqBaseListViewItem::KonqBaseListViewItem(KonqBaseListViewWidget *_listViewWidget, KFileItem* _fileitem) +:KListViewItem(_listViewWidget) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_pListViewWidget(_listViewWidget) +{} + +KonqBaseListViewItem::KonqBaseListViewItem(KonqBaseListViewWidget *_listViewWidget, KonqBaseListViewItem *_parent, KFileItem* _fileitem) +:KListViewItem(_parent) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_pListViewWidget(_listViewWidget) +{} + +KonqBaseListViewItem::~KonqBaseListViewItem() +{ + if (m_pListViewWidget->m_activeItem == this) + m_pListViewWidget->m_activeItem = 0; + if (m_pListViewWidget->m_dragOverItem == this) + m_pListViewWidget->m_dragOverItem = 0; + + if (m_pListViewWidget->m_selected) + m_pListViewWidget->m_selected->removeRef(this); +} + +QRect KonqBaseListViewItem::rect() const +{ + QRect r = m_pListViewWidget->itemRect(this); + return QRect( m_pListViewWidget->viewportToContents( r.topLeft() ), QSize( r.width(), r.height() ) ); +} + +void KonqBaseListViewItem::mimetypeFound() +{ + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = m_pListViewWidget; + for (unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms && done < 2; i++) + { + ColumnInfo *tmpColumn=&lv->columnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_MIME_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimetype()); + done++; + } + } +} + diff --git a/konqueror/listview/konq_listviewitems.h b/konqueror/listview/konq_listviewitems.h new file mode 100644 index 000000000..6e0cbc513 --- /dev/null +++ b/konqueror/listview/konq_listviewitems.h @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 __konq_listviewitems_h__ +#define __konq_listviewitems_h__ + +#include <klistview.h> +#include <qstring.h> +#include <kicontheme.h> + +#include <qvaluevector.h> + +// for mode_t +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +class QPainter; +class KFileItem; +class KonqBaseListViewWidget; + + +class KonqBaseListViewItem : public KListViewItem +{ + public: + KonqBaseListViewItem( KonqBaseListViewWidget *_listViewWidget, + KFileItem *_fileitem ); + KonqBaseListViewItem( KonqBaseListViewWidget *_treeViewWidget, + KonqBaseListViewItem *_parent, KFileItem *_fileitem ); + virtual ~KonqBaseListViewItem(); + + /** @return the file item held by this instance */ + KFileItem * item() { return m_fileitem; } + + void mimetypeFound(); + virtual void updateContents() = 0; + virtual void setDisabled( bool disabled ) { m_bDisabled = disabled; } + virtual void setActive ( bool active ) { m_bActive = active; } + virtual int compare( QListViewItem* i, int col, bool ascending ) const; + + int state() const + { + if (m_bDisabled) + return KIcon::DisabledState; + if (m_bActive) + return KIcon::ActiveState; + return KIcon::DefaultState; + } + + /** For KonqMimeTypeResolver */ + QRect rect() const; + + protected: + short int sortChar; + bool m_bDisabled; + bool m_bActive; + + /** Pointer to the file item in KDirLister's list */ + KFileItem* m_fileitem; + /** Parent tree view */ + KonqBaseListViewWidget* m_pListViewWidget; + + /** + * @deprecated Use KFileItem::permissionsString() instead + */ + static const char* makeAccessString( const mode_t mode ); +}; + +/** + * One item in the detailed list or in the tree (not text) + */ +class KonqListViewItem : public KonqBaseListViewItem +{ + public: + /** + * Create an item in the tree toplevel representing a file + * @param _parent the parent widget, the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewItem( KonqBaseListViewWidget *_parent, KFileItem *_fileitem ); + + /** + * Create an item representing a file, inside a directory + * @param _treeview the parent tree view + * @param _parent the parent widget, a directory item in the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewItem( KonqBaseListViewWidget *_treeview, + KonqListViewItem *_parent, KFileItem *_fileitem ); + + virtual ~KonqListViewItem(); + + virtual void paintCell( QPainter *_painter, const QColorGroup & cg, + int column, int width, int alignment ); + virtual void paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & r ); + virtual void updateContents(); + virtual void setDisabled( bool disabled ); + virtual void setActive ( bool active ); + + virtual void setPixmap( int column, const QPixmap & pm ); + virtual const QPixmap * pixmap( int column ) const; + +private: + QValueVector<QPixmap *> m_pixmaps; +}; + +#endif diff --git a/konqueror/listview/konq_listviewsettings.kcfgc b/konqueror/listview/konq_listviewsettings.kcfgc new file mode 100644 index 000000000..227521fe0 --- /dev/null +++ b/konqueror/listview/konq_listviewsettings.kcfgc @@ -0,0 +1,4 @@ +File=konq_listview.kcfg +ClassName=KonqListViewSettings +Singleton=false +Mutators=true
\ No newline at end of file diff --git a/konqueror/listview/konq_listviewwidget.cc b/konqueror/listview/konq_listviewwidget.cc new file mode 100644 index 000000000..f3016b433 --- /dev/null +++ b/konqueror/listview/konq_listviewwidget.cc @@ -0,0 +1,1416 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + 2001, 2002, 2004 Michael Brade <[email protected]> + + 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_listview.h" +#include "konq_listviewsettings.h" +#include "konq_listviewwidget.h" +#include <konq_filetip.h> +#include <konq_drag.h> +#include <konq_settings.h> + +#include <kdebug.h> +#include <kdirlister.h> +#include <klocale.h> +#include <kprotocolinfo.h> +#include <kaction.h> +#include <kurldrag.h> +#include <kmessagebox.h> +#include <kiconloader.h> + +#include <qheader.h> +#include <qpainter.h> +#include <qstyle.h> +#include <qtimer.h> +#include <qevent.h> +#include <qcursor.h> +#include <qtooltip.h> + +#include <stdlib.h> +#include <assert.h> + +ColumnInfo::ColumnInfo() + :displayInColumn(-1) + ,name() + ,desktopFileName() + ,udsId(0) + ,type(QVariant::Invalid) + ,displayThisOne(false) + ,toggleThisOne(0) +{} + + +void ColumnInfo::setData(const QString& n, const QString& desktopName, int kioUds, + KToggleAction* someAction, int theWidth) +{ + displayInColumn=-1; + name=n; + desktopFileName=desktopName; + udsId=kioUds; + type=QVariant::Invalid; + displayThisOne=false; + toggleThisOne=someAction; + width=theWidth; +} + +void ColumnInfo::setData(const QString& n, const QString& desktopName, int kioUds, + QVariant::Type t, KToggleAction* someAction, int theWidth) +{ + displayInColumn=-1; + name=n; + desktopFileName=desktopName; + udsId=kioUds; + type=t; + displayThisOne=false; + toggleThisOne=someAction; + width=theWidth; +} + + +KonqBaseListViewWidget::KonqBaseListViewWidget( KonqListView *parent, QWidget *parentWidget) + : KListView(parentWidget) + ,sortedByColumn(0) + ,m_pBrowserView(parent) + ,m_dirLister(new KDirLister( true /*m_showIcons==false*/)) + ,m_dragOverItem(0) + ,m_activeItem(0) + ,m_selected(0) + ,m_scrollTimer(0) + ,m_rubber(0) + ,m_showIcons(true) + ,m_bCaseInsensitive(true) + ,m_bUpdateContentsPosAfterListing(false) + ,m_bAscending(true) + ,m_itemFound(false) + ,m_restored(false) + ,m_filenameColumn(0) + ,m_itemToGoTo("") + ,m_backgroundTimer(0) + ,m_fileTip(new KonqFileTip(this)) +{ + kdDebug(1202) << "+KonqBaseListViewWidget" << endl; + + m_dirLister->setMainWindow(topLevelWidget()); + + m_bTopLevelComplete = true; + + //Adjust KListView behaviour + setMultiSelection(true); + setSelectionModeExt( FileManager ); + setDragEnabled(true); + setItemsMovable(false); + + initConfig(); +#if 0 + connect( this, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint&,int)), + this, SLOT(slotRightButtonPressed(QListViewItem*,const QPoint&,int))); +#endif + connect( this, SIGNAL(returnPressed( QListViewItem * )), + this, SLOT(slotReturnPressed( QListViewItem * )) ); + connect( this, SIGNAL( mouseButtonClicked( int, QListViewItem *, const QPoint&, int )), + this, SLOT( slotMouseButtonClicked2( int, QListViewItem *, const QPoint&, int )) ); + connect( this, SIGNAL(executed( QListViewItem * )), + this, SLOT(slotExecuted( QListViewItem * )) ); + + connect( this, SIGNAL(currentChanged( QListViewItem * )), + this, SLOT(slotCurrentChanged( QListViewItem * )) ); + connect( this, SIGNAL(itemRenamed( QListViewItem *, const QString &, int )), + this, SLOT(slotItemRenamed( QListViewItem *, const QString &, int )) ); + connect( this, SIGNAL(contextMenuRequested( QListViewItem *, const QPoint&, int )), + this, SLOT(slotPopupMenu( QListViewItem *, const QPoint&, int )) ); + connect( this, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) ); + + connect( horizontalScrollBar(), SIGNAL(valueChanged( int )), + this, SIGNAL(viewportAdjusted()) ); + connect( verticalScrollBar(), SIGNAL(valueChanged( int )), + this, SIGNAL(viewportAdjusted()) ); + + // Connect the directory lister + connect( m_dirLister, SIGNAL(started( const KURL & )), + this, SLOT(slotStarted()) ); + connect( m_dirLister, SIGNAL(completed()), this, SLOT(slotCompleted()) ); + connect( m_dirLister, SIGNAL(canceled()), this, SLOT(slotCanceled()) ); + 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 & )), + m_pBrowserView, SIGNAL(itemsFilteredByMime( const KFileItemList & )) ); + + connect( m_dirLister, SIGNAL(infoMessage( const QString& )), + m_pBrowserView->extension(), SIGNAL(infoMessage( const QString& )) ); + connect( m_dirLister, SIGNAL(percent( int )), + m_pBrowserView->extension(), SIGNAL(loadingProgress( int )) ); + connect( m_dirLister, SIGNAL(speed( int )), + m_pBrowserView->extension(), SIGNAL(speedProgress( int )) ); + + connect( header(), SIGNAL(sizeChange( int, int, int )), SLOT(slotUpdateBackground()) ); + + viewport()->setMouseTracking( true ); + viewport()->setFocusPolicy( QWidget::WheelFocus ); + setFocusPolicy( QWidget::WheelFocus ); + setAcceptDrops( true ); + + //looks better with the statusbar + setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + setShowSortIndicator( true ); +} + +KonqBaseListViewWidget::~KonqBaseListViewWidget() +{ + kdDebug(1202) << "-KonqBaseListViewWidget" << endl; + + delete m_selected; m_selected = 0; + + // TODO: this is a hack, better fix the connections of m_dirLister if possible! + m_dirLister->disconnect( this ); + delete m_dirLister; + + delete m_fileTip; +} + +void KonqBaseListViewWidget::readProtocolConfig( const KURL & url ) +{ + const QString protocol = url.protocol(); + KonqListViewSettings config( protocol ); + config.readConfig(); + sortedByColumn = config.sortBy(); + m_bAscending = config.sortOrder(); + + m_filenameColumnWidth = config.fileNameColumnWidth(); + + QStringList lstColumns = config.columns(); + QValueList<int> lstColumnWidths = config.columnWidths(); + if (lstColumns.isEmpty()) + { + // Default column selection + lstColumns.append( "Size" ); + lstColumns.append( "File Type" ); + lstColumns.append( "Modified" ); + lstColumns.append( "Permissions" ); + lstColumns.append( "Owner" ); + lstColumns.append( "Group" ); + lstColumns.append( "Link" ); + } + + // Default number of columns + NumberOfAtoms = 11; + int extraIndex = NumberOfAtoms; + + // Check for any extra data + KProtocolInfo::ExtraFieldList extraFields = KProtocolInfo::extraFields(url); + NumberOfAtoms += extraFields.count(); + confColumns.resize( NumberOfAtoms ); + + KProtocolInfo::ExtraFieldList::Iterator extraFieldsIt = extraFields.begin(); + for ( int num = 1; extraFieldsIt != extraFields.end(); ++extraFieldsIt, ++num ) + { + const QString column = (*extraFieldsIt).name; + if ( lstColumns.find(column) == lstColumns.end() ) + lstColumns << column; + const QString type = (*extraFieldsIt).type; // ## TODO use when sorting + QVariant::Type t = QVariant::Invalid; + if ( type.lower() == "qstring" ) + t = QVariant::String; + else if ( type.lower() == "qdatetime" ) + t = QVariant::DateTime; + else + kdWarning() << "Unsupported ExtraType '" << type << "'" << endl; + confColumns[extraIndex++].setData( column, QString("Extra%1").arg(num), KIO::UDS_EXTRA, t, 0); + } + + //disable everything + for ( unsigned int i = 0; i < NumberOfAtoms; i++ ) + { + confColumns[i].displayThisOne = false; + confColumns[i].displayInColumn = -1; + if ( confColumns[i].toggleThisOne ) + { + confColumns[i].toggleThisOne->setChecked( false ); + confColumns[i].toggleThisOne->setEnabled( true ); + } + } + int currentColumn = m_filenameColumn + 1; + //check all columns in lstColumns + for ( unsigned int i = 0; i < lstColumns.count(); i++ ) + { + //search the column in confColumns + for ( unsigned int j = 0; j < NumberOfAtoms; j++ ) + { + if ( confColumns[j].name == *lstColumns.at(i) ) + { + confColumns[j].displayThisOne = true; + confColumns[j].displayInColumn = currentColumn; + if ( confColumns[j].toggleThisOne ) + confColumns[j].toggleThisOne->setChecked( true ); + currentColumn++; + + if ( i < lstColumnWidths.count() ) + confColumns[j].width = *lstColumnWidths.at(i); + else + { + // Default Column widths + ColumnInfo *tmpColumn = &confColumns[j]; + QString str; + + if ( tmpColumn->udsId == KIO::UDS_SIZE ) + str = KGlobal::locale()->formatNumber( 888888888, 0 ) + " "; + else if ( tmpColumn->udsId == KIO::UDS_ACCESS ) + str = "--Permissions--"; + else if ( tmpColumn->udsId == KIO::UDS_USER ) + str = "a_long_username"; + else if ( tmpColumn->udsId == KIO::UDS_GROUP ) + str = "a_groupname"; + else if ( tmpColumn->udsId == KIO::UDS_LINK_DEST ) + str = "a_quite_long_filename_for_link_dest"; + else if ( tmpColumn->udsId == KIO::UDS_FILE_TYPE ) + str = "a_long_comment_for_mimetype"; + else if ( tmpColumn->udsId == KIO::UDS_MIME_TYPE ) + str = "_a_long_/_mimetype_"; + else if ( tmpColumn->udsId == KIO::UDS_URL ) + str = "a_long_lonq_long_very_long_url"; + else if ( (tmpColumn->udsId & KIO::UDS_TIME) + || (tmpColumn->udsId == KIO::UDS_EXTRA && + (tmpColumn->type & QVariant::DateTime)) ) + { + QDateTime dt( QDate( 2000, 10, 10 ), QTime( 20, 20, 20 ) ); + str = KGlobal::locale()->formatDateTime( dt ) + "--"; + } + else + str = "it_is_the_default_width"; + + confColumns[j].width = fontMetrics().width(str); + } + break; + } + } + } + //check what the protocol provides + QStringList listingList = KProtocolInfo::listing( url ); + kdDebug(1202) << k_funcinfo << "protocol: " << protocol << endl; + + // Even if this is not given by the protocol, we can determine it. + // Please don't remove this ;-). It makes it possible to show the file type + // using the mimetype comment, which for most users is a nicer alternative + // than the raw mimetype name. + listingList.append( "MimeType" ); + for ( unsigned int i = 0; i < NumberOfAtoms; i++ ) + { + if ( confColumns[i].udsId == KIO::UDS_URL || + confColumns[i].udsId == KIO::UDS_MIME_TYPE || + !confColumns[i].displayThisOne ) + { + continue; + } + + QStringList::Iterator listIt = listingList.find( confColumns[i].desktopFileName ); + if ( listIt == listingList.end() ) // not found -> hide + { + //move all columns behind one to the front + for ( unsigned int l = 0; l < NumberOfAtoms; l++ ) + if ( confColumns[l].displayInColumn > confColumns[i].displayInColumn ) + confColumns[l].displayInColumn--; + + //disable this column + confColumns[i].displayThisOne = false; + if ( confColumns[i].toggleThisOne ) + { + confColumns[i].toggleThisOne->setEnabled( false ); + confColumns[i].toggleThisOne->setChecked( false ); + } + } + } +} + +void KonqBaseListViewWidget::createColumns() +{ + //this column is always required, so add it + if ( columns() < 1 ) + addColumn( i18n("Name"), m_filenameColumnWidth ); + setSorting( 0, true ); + + //remove all columns that will be re-added + for ( int i=columns()-1; i>m_filenameColumn; i--) + removeColumn(i); + + //now add the checked columns + int currentColumn = m_filenameColumn + 1; + for ( int i = 0; i < (int)NumberOfAtoms; i++ ) + { + if ( confColumns[i].displayThisOne && (confColumns[i].displayInColumn == currentColumn) ) + { + addColumn( i18n(confColumns[i].name.utf8()), confColumns[i].width ); + if ( sortedByColumn == confColumns[i].desktopFileName ) + setSorting( currentColumn, m_bAscending ); + if ( confColumns[i].udsId == KIO::UDS_SIZE ) + setColumnAlignment( currentColumn, AlignRight ); + i = -1; + currentColumn++; + } + } + if ( sortedByColumn == "FileName" ) + setSorting( 0, m_bAscending ); +} + +void KonqBaseListViewWidget::stop() +{ + m_dirLister->stop(); +} + +const KURL & KonqBaseListViewWidget::url() +{ + return m_url; +} + +void KonqBaseListViewWidget::initConfig() +{ + m_pSettings = KonqFMSettings::settings(); + + QFont stdFont( m_pSettings->standardFont() ); + setFont( stdFont ); + //TODO: create config GUI + QFont itemFont( m_pSettings->standardFont() ); + itemFont.setUnderline( m_pSettings->underlineLink() ); + setItemFont( itemFont ); + setItemColor( m_pSettings->normalTextColor() ); + + bool on = m_pSettings->showFileTips() && QToolTip::isGloballyEnabled(); + m_fileTip->setOptions( on, m_pSettings->showPreviewsInFileTips(), m_pSettings->numFileTips() ); + + updateListContents(); +} + +void KonqBaseListViewWidget::contentsMousePressEvent( QMouseEvent *e ) +{ + if ( m_rubber ) + { + drawRubber(); + delete m_rubber; + m_rubber = 0; + } + + delete m_selected; + m_selected = new QPtrList<KonqBaseListViewItem>; + + QPoint vp = contentsToViewport( e->pos() ); + KonqBaseListViewItem* item = isExecuteArea( vp ) ? + static_cast<KonqBaseListViewItem*>( itemAt( vp ) ) : 0L; + + if ( item ) + KListView::contentsMousePressEvent( e ); + else { + if ( e->button() == LeftButton ) + { + if ( !( e->state() & ControlButton ) ) + setSelected( itemAt( vp ), false ); + m_rubber = new QRect( e->x(), e->y(), 0, 0 ); + m_fileTip->setItem( 0 ); + } + if ( e->button() != RightButton ) + QListView::contentsMousePressEvent( e ); + } + // Store list of selected items at mouse-press time. + // This is used when autoscrolling (why?) + // and during dnd (the target item is temporarily selected) + selectedItems( m_selected ); +} + +void KonqBaseListViewWidget::contentsMouseReleaseEvent( QMouseEvent *e ) +{ + if ( m_rubber ) + { + drawRubber(); + delete m_rubber; + m_rubber = 0; + } + + if ( m_scrollTimer ) + { + disconnect( m_scrollTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoScroll() ) ); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } + + delete m_selected; m_selected = 0; + KListView::contentsMouseReleaseEvent( e ); +} + +void KonqBaseListViewWidget::contentsMouseMoveEvent( QMouseEvent *e ) +{ + if ( m_rubber ) + { + slotAutoScroll(); + return; + } + + QPoint vp = contentsToViewport( e->pos() ); + KonqBaseListViewItem* item = isExecuteArea( vp ) ? + static_cast<KonqBaseListViewItem *>( itemAt( vp ) ) : 0; + + if ( item != m_activeItem ) + { + if ( m_activeItem != 0 ) + m_activeItem->setActive( false ); + + m_activeItem = item; + + if ( item ) + { + item->setActive( true ); + emit m_pBrowserView->setStatusBarText( item->item()->getStatusBarInfo() ); + m_pBrowserView->emitMouseOver( item->item() ); + + vp.setY( itemRect( item ).y() ); + QRect rect( viewportToContents( vp ), QSize(20, item->height()) ); + m_fileTip->setItem( item->item(), rect, item->pixmap( 0 ) ); + m_fileTip->setPreview( KGlobalSettings::showFilePreview( item->item()->url() ) ); + setShowToolTips( !m_pSettings->showFileTips() ); + } + else + { + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + + m_fileTip->setItem( 0 ); + setShowToolTips( true ); + } + } + + KListView::contentsMouseMoveEvent( e ); +} + +void KonqBaseListViewWidget::contentsWheelEvent( QWheelEvent *e ) +{ + // when scrolling with mousewheel, stop possible pending filetip + m_fileTip->setItem( 0 ); + + if ( m_activeItem != 0 ) + { + m_activeItem->setActive( false ); + m_activeItem = 0; + } + + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + KListView::contentsWheelEvent( e ); +} + +void KonqBaseListViewWidget::leaveEvent( QEvent *e ) +{ + if ( m_activeItem != 0 ) + { + m_activeItem->setActive( false ); + m_activeItem = 0; + } + + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + + m_fileTip->setItem( 0 ); + + KListView::leaveEvent( e ); +} + +void KonqBaseListViewWidget::drawRubber() +{ + if ( !m_rubber ) + return; + + QPainter p; + p.begin( viewport() ); + p.setRasterOp( NotROP ); + p.setPen( QPen( color0, 1 ) ); + p.setBrush( NoBrush ); + + QPoint pt( m_rubber->x(), m_rubber->y() ); + pt = contentsToViewport( pt ); + style().drawPrimitive( QStyle::PE_FocusRect, &p, + QRect( pt.x(), pt.y(), m_rubber->width(), m_rubber->height() ), + colorGroup(), QStyle::Style_Default, colorGroup().base() ); + p.end(); +} + +void KonqBaseListViewWidget::slotAutoScroll() +{ + if ( !m_rubber ) + return; + + // this code assumes that all items have the same height + + const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() ); + const QPoint vc = viewportToContents( pos ); + + if ( vc == m_rubber->bottomRight() ) + return; + + const int oldTop = m_rubber->normalize().top(); + const int oldBottom = m_rubber->normalize().bottom(); + + drawRubber(); + m_rubber->setBottomRight( vc ); + + QListViewItem *cur = itemAt( QPoint(0,0) ); + + bool block = signalsBlocked(); + blockSignals( true ); + + QRect nr = m_rubber->normalize(); + if ( cur ) + { + QRect rect = itemRect( cur ); + if ( !allColumnsShowFocus() ) + rect.setWidth( executeArea( cur ) ); + + rect = QRect( viewportToContents( rect.topLeft() ), + viewportToContents( rect.bottomRight() ) ); + + if ( !allColumnsShowFocus() ) + { + rect.setLeft( header()->sectionPos( 0 ) ); + rect.setWidth( rect.width() ); + } + else + { + rect.setLeft( 0 ); + rect.setWidth( header()->headerWidth() ); + } + + QRect r = rect; + QListViewItem *tmp = cur; + + while ( cur && rect.top() <= oldBottom ) + { + if ( rect.intersects( nr ) ) + { + if ( !cur->isSelected() && cur->isSelectable() ) + setSelected( cur, true ); + } else if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + setSelected( cur, false ); + + cur = cur->itemBelow(); + if (cur && !allColumnsShowFocus()) + rect.setWidth( executeArea( cur ) ); + rect.moveBy( 0, rect.height() ); + } + + rect = r; + rect.moveBy( 0, -rect.height() ); + cur = tmp->itemAbove(); + + while ( cur && rect.bottom() >= oldTop ) + { + if ( rect.intersects( nr ) ) + { + if ( !cur->isSelected() && cur->isSelectable() ) + setSelected( cur, true ); + } else if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + setSelected( cur, false ); + + cur = cur->itemAbove(); + if (cur && !allColumnsShowFocus()) + rect.setWidth( executeArea( cur ) ); + rect.moveBy( 0, -rect.height() ); + } + } + + blockSignals( block ); + emit selectionChanged(); + + drawRubber(); + + const int scroll_margin = 40; + ensureVisible( vc.x(), vc.y(), scroll_margin, scroll_margin ); + + if ( !QRect( scroll_margin, scroll_margin, + viewport()->width() - 2*scroll_margin, + viewport()->height() - 2*scroll_margin ).contains( pos ) ) + { + if ( !m_scrollTimer ) + { + m_scrollTimer = new QTimer( this ); + + connect( m_scrollTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoScroll() ) ); + m_scrollTimer->start( 100, false ); + } + } + else if ( m_scrollTimer ) + { + disconnect( m_scrollTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoScroll() ) ); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } +} + +void KonqBaseListViewWidget::viewportPaintEvent( QPaintEvent *e ) +{ + drawRubber(); + KListView::viewportPaintEvent( e ); + drawRubber(); +} + +void KonqBaseListViewWidget::viewportResizeEvent(QResizeEvent * e) +{ + KListView::viewportResizeEvent(e); + emit viewportAdjusted(); +} + +void KonqBaseListViewWidget::viewportDragMoveEvent( QDragMoveEvent *_ev ) +{ + KonqBaseListViewItem *item = + isExecuteArea( _ev->pos() ) ? (KonqBaseListViewItem*)itemAt( _ev->pos() ) : 0L; + + // Unselect previous drag-over-item + if ( m_dragOverItem && m_dragOverItem != item ) + if ( !m_selected || !m_selected->contains( m_dragOverItem ) ) + setSelected( m_dragOverItem, false ); + + if ( !item ) + { + _ev->acceptAction(); + m_dragOverItem = 0L; + return; + } + + if ( item->item()->acceptsDrops() ) + { + _ev->acceptAction(); + if ( m_dragOverItem != item ) + { + setSelected( item, true ); + m_dragOverItem = item; + } + } + else + { + _ev->ignore(); + m_dragOverItem = 0L; + } +} + +void KonqBaseListViewWidget::viewportDragEnterEvent( QDragEnterEvent *_ev ) +{ + m_dragOverItem = 0L; + + // By default we accept any format + _ev->acceptAction(); +} + +void KonqBaseListViewWidget::viewportDragLeaveEvent( QDragLeaveEvent * ) +{ + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + m_dragOverItem = 0L; +} + +void KonqBaseListViewWidget::viewportDropEvent( QDropEvent *ev ) +{ + if ( m_dirLister->url().isEmpty() ) + return; + kdDebug() << "KonqBaseListViewWidget::viewportDropEvent" << endl; + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + m_dragOverItem = 0L; + + ev->accept(); + + // We dropped on an item only if we dropped on the Name column. + KonqBaseListViewItem *item = + isExecuteArea( ev->pos() ) ? (KonqBaseListViewItem*)itemAt( ev->pos() ) : 0; + + KFileItem * destItem = (item) ? item->item() : m_dirLister->rootItem(); + KURL u = destItem ? destItem->url() : url(); + if ( u.isEmpty() ) + return; + KonqOperations::doDrop( destItem /*may be 0L*/, u, ev, this ); +} + +void KonqBaseListViewWidget::startDrag() +{ + m_fileTip->setItem( 0 ); + KURL::List urls = selectedUrls( false ); + + QListViewItem * m_pressedItem = currentItem(); + + QPixmap pixmap2; + bool pixmap0Invalid = !m_pressedItem->pixmap(0) || m_pressedItem->pixmap(0)->isNull(); + + // Multiple URLs ? + if (( urls.count() > 1 ) || (pixmap0Invalid)) + { + int iconSize = m_pBrowserView->m_pProps->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + pixmap2 = DesktopIcon( "kmultiple", iconSize ); + if ( pixmap2.isNull() ) + kdWarning(1202) << "Could not find multiple pixmap" << endl; + } + + //KURLDrag *d = new KURLDrag( urls, viewport() ); + KonqDrag *drag= new KonqDrag( urls, selectedUrls(true), false, viewport() ); + if ( !pixmap2.isNull() ) + drag->setPixmap( pixmap2 ); + else if ( !pixmap0Invalid ) + drag->setPixmap( *m_pressedItem->pixmap( 0 ) ); + + drag->drag(); +} + +void KonqBaseListViewWidget::slotItemRenamed( QListViewItem *item, const QString &name, int col ) +{ + Q_ASSERT( col == 0 ); + Q_ASSERT( item != 0 ); + + // The correct behavior is to show the old name until the rename has successfully + // completed. Unfortunately, KListView forces us to allow the text to be changed + // before we try the rename, so set it back to the pre-rename state. + KonqBaseListViewItem *renamedItem = static_cast<KonqBaseListViewItem*>(item); + renamedItem->updateContents(); + + // Don't do anything if the user renamed to a blank name. + if( !name.isEmpty() ) + { + // Actually attempt the rename. If it succeeds, KDirLister will update the name. + KonqOperations::rename( this, renamedItem->item()->url(), KIO::encodeFileName( name ) ); + } + + // When the KListViewLineEdit loses focus, focus tends to go to the location bar... + setFocus(); +} + +void KonqBaseListViewWidget::reportItemCounts() +{ + KFileItemList lst = selectedFileItems(); + if ( !lst.isEmpty() ) + m_pBrowserView->emitCounts( lst ); + else + { + lst = visibleFileItems(); + m_pBrowserView->emitCounts( lst ); + } +} + +void KonqBaseListViewWidget::slotSelectionChanged() +{ + reportItemCounts(); + + KFileItemList lst = selectedFileItems(); + emit m_pBrowserView->m_extension->selectionInfo( lst ); +} + +void KonqBaseListViewWidget::slotMouseButtonClicked2( int _button, + QListViewItem *_item, const QPoint& pos, int ) +{ + if ( _button == MidButton ) + { + if ( _item && isExecuteArea( viewport()->mapFromGlobal(pos) ) ) + m_pBrowserView->mmbClicked( static_cast<KonqBaseListViewItem *>(_item)->item() ); + else // MMB on background + m_pBrowserView->mmbClicked( 0 ); + } +} + +void KonqBaseListViewWidget::slotExecuted( QListViewItem *item ) +{ + if ( !item ) + return; + m_fileTip->setItem( 0 ); + // isExecuteArea() checks whether the mouse pointer is + // over an area where an action should be triggered + // (i.e. the Name column, including pixmap and "+") + if ( isExecuteArea( viewport()->mapFromGlobal( QCursor::pos() ) ) ) + slotReturnPressed( item ); +} + +void KonqBaseListViewWidget::selectedItems( QPtrList<KonqBaseListViewItem> *_list ) +{ + iterator it = begin(); + for ( ; it != end(); it++ ) + if ( it->isSelected() ) + _list->append( &*it ); +} + +KFileItemList KonqBaseListViewWidget::visibleFileItems() +{ + KFileItemList list; + KonqBaseListViewItem *item = static_cast<KonqBaseListViewItem *>(firstChild()); + while ( item ) + { + list.append( item->item() ); + item = static_cast<KonqBaseListViewItem *>(item->itemBelow()); + } + return list; +} + +KFileItemList KonqBaseListViewWidget::selectedFileItems() +{ + KFileItemList list; + iterator it = begin(); + for ( ; it != end(); it++ ) + if ( it->isSelected() ) + list.append( it->item() ); + return list; +} + +KURL::List KonqBaseListViewWidget::selectedUrls( bool mostLocal ) +{ + bool dummy; + KURL::List list; + iterator it = begin(); + for ( ; it != end(); it++ ) + if ( it->isSelected() ) + list.append( mostLocal ? it->item()->mostLocalURL( dummy ) : it->item()->url() ); + return list; +} + +KonqPropsView * KonqBaseListViewWidget::props() const +{ + return m_pBrowserView->m_pProps; +} + +void KonqBaseListViewWidget::slotReturnPressed( QListViewItem *_item ) +{ + if ( !_item ) + return; + KFileItem *fileItem = static_cast<KonqBaseListViewItem *>(_item)->item(); + if ( !fileItem ) + return; + + KURL url = fileItem->url(); + url.cleanPath(); + bool isIntoTrash = url.isLocalFile() && url.path(1).startsWith(KGlobalSettings::trashPath()); + if ( !isIntoTrash || (isIntoTrash && fileItem->isDir()) ) + m_pBrowserView->lmbClicked( fileItem ); + else + KMessageBox::information( 0, i18n("You must take the file out of the trash before being able to use it.") ); +} + +void KonqBaseListViewWidget::slotPopupMenu( QListViewItem *i, const QPoint &point, int c ) +{ + kdDebug(1202) << "KonqBaseListViewWidget::slotPopupMenu" << endl; + popupMenu( point, ( i != 0 && c == -1 ) ); // i != 0 && c == -1 when activated by keyboard +} + +void KonqBaseListViewWidget::popupMenu( const QPoint& _global, bool alwaysForSelectedFiles ) +{ + m_fileTip->setItem( 0 ); + + KFileItemList lstItems; + KParts::BrowserExtension::PopupFlags popupFlags = KParts::BrowserExtension::DefaultPopupItems; + + // Only consider a right-click on the name column as something + // related to the selection. On all the other columns, we want + // a popup for the current dir instead. + if ( alwaysForSelectedFiles || isExecuteArea( viewport()->mapFromGlobal( _global ) ) ) + { + QPtrList<KonqBaseListViewItem> items; + selectedItems( &items ); + for ( KonqBaseListViewItem *item = items.first(); item; item = items.next() ) + lstItems.append( item->item() ); + } + + KFileItem *rootItem = 0L; + bool deleteRootItem = false; + if ( lstItems.count() == 0 ) // emit popup for background + { + clearSelection(); + + if ( m_dirLister->url().isEmpty() ) + return; + rootItem = m_dirLister->rootItem(); + if ( !rootItem ) + { + if ( url().isEmpty() ) + return; + // Maybe we want to do a stat to get full info about the root item + // (when we use permissions). For now create a dummy one. + rootItem = new KFileItem( S_IFDIR, (mode_t)-1, url() ); + deleteRootItem = true; + } + + lstItems.append( rootItem ); + popupFlags = KParts::BrowserExtension::ShowNavigationItems | KParts::BrowserExtension::ShowUp; + } + emit m_pBrowserView->extension()->popupMenu( 0, _global, lstItems, KParts::URLArgs(), popupFlags ); + + if ( deleteRootItem ) + delete rootItem; // we just created it +} + +void KonqBaseListViewWidget::updateListContents() +{ + for ( KonqBaseListViewWidget::iterator it = begin(); it != end(); it++ ) + it->updateContents(); +} + +bool KonqBaseListViewWidget::openURL( const KURL &url ) +{ + kdDebug(1202) << k_funcinfo << "protocol: " << url.protocol() + << " url: " << url.path() << endl; + + // The first time or new protocol? So create the columns first. + if ( columns() < 1 || url.protocol() != m_url.protocol() ) + { + readProtocolConfig( url ); + createColumns(); + } + + m_bTopLevelComplete = false; + m_itemFound = false; + + if ( m_itemToGoTo.isEmpty() && url.equals( m_url.upURL(), true ) ) + m_itemToGoTo = m_url.fileName( true ); + + // Check for new properties in the new dir + // newProps returns true the first time, and any time something might + // have changed. + bool newProps = m_pBrowserView->m_pProps->enterDir( url ); + + m_dirLister->setNameFilter( m_pBrowserView->nameFilter() ); + m_dirLister->setMimeFilter( m_pBrowserView->mimeFilter() ); + m_dirLister->setShowingDotFiles( m_pBrowserView->m_pProps->isShowingDotFiles() ); + + KParts::URLArgs args = m_pBrowserView->extension()->urlArgs(); + if ( args.reload ) + { + args.xOffset = contentsX(); + args.yOffset = contentsY(); + m_pBrowserView->extension()->setURLArgs( args ); + + if ( currentItem() && itemRect( currentItem() ).isValid() ) + m_itemToGoTo = currentItem()->text(0); + + m_pBrowserView->m_filesToSelect.clear(); + iterator it = begin(); + for( ; it != end(); it++ ) + if ( it->isSelected() ) + m_pBrowserView->m_filesToSelect += it->text(0); + } + + m_itemsToSelect = m_pBrowserView->m_filesToSelect; + if ( !m_itemsToSelect.isEmpty() && m_itemToGoTo.isEmpty() ) + m_itemToGoTo = m_itemsToSelect[0]; + + if ( columnWidthMode(0) == Maximum ) + setColumnWidth(0,50); + + m_url = url; + m_bUpdateContentsPosAfterListing = true; + + // Start the directory lister ! + m_dirLister->openURL( url, false /* new url */, args.reload ); + + // Apply properties and reflect them on the actions + // do it after starting the dir lister to avoid changing the properties + // of the old view + if ( newProps ) + { + m_pBrowserView->newIconSize( m_pBrowserView->m_pProps->iconSize() ); + m_pBrowserView->m_paShowDot->setChecked( m_pBrowserView->m_pProps->isShowingDotFiles() ); + if ( m_pBrowserView->m_paCaseInsensitive->isChecked() != m_pBrowserView->m_pProps->isCaseInsensitiveSort() ) { + m_pBrowserView->m_paCaseInsensitive->setChecked( m_pBrowserView->m_pProps->isCaseInsensitiveSort() ); + // This is in case openURL returned all items synchronously. + sort(); + } + + // It has to be "viewport()" - this is what KonqDirPart's slots act upon, + // and otherwise we get a color/pixmap in the square between the scrollbars. + m_pBrowserView->m_pProps->applyColors( viewport() ); + } + + return true; +} + +void KonqBaseListViewWidget::setComplete() +{ + kdDebug(1202) << k_funcinfo << "Update Contents Pos: " + << m_bUpdateContentsPosAfterListing << endl; + + m_bTopLevelComplete = true; + + // Alex: this flag is set when we are just finishing a voluntary listing, + // so do the go-to-item thing only under here. When we update the + // current directory automatically (e.g. after a file has been deleted), + // we don't want to go to the first item ! (David) + if ( m_bUpdateContentsPosAfterListing ) + { + m_bUpdateContentsPosAfterListing = false; + + if ( !m_itemFound ) + setCurrentItem( firstChild() ); + + if ( !m_restored && !m_pBrowserView->extension()->urlArgs().reload ) + ensureItemVisible( currentItem() ); + else + setContentsPos( m_pBrowserView->extension()->urlArgs().xOffset, + m_pBrowserView->extension()->urlArgs().yOffset ); + + emit selectionChanged(); + } + + m_itemToGoTo = ""; + m_restored = false; + + // Show totals + reportItemCounts(); + + m_pBrowserView->emitMouseOver( 0 ); + + if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + + // Show "cut" icons as such + m_pBrowserView->slotClipboardDataChanged(); +} + +void KonqBaseListViewWidget::slotStarted() +{ + //kdDebug(1202) << k_funcinfo << endl; + + if (!m_bTopLevelComplete) + emit m_pBrowserView->started( 0 ); +} + +void KonqBaseListViewWidget::slotCompleted() +{ + //kdDebug(1202) << k_funcinfo << endl; + + setComplete(); + if ( m_bTopLevelComplete ) + emit m_pBrowserView->completed(); + m_pBrowserView->listingComplete(); +} + +void KonqBaseListViewWidget::slotCanceled() +{ + //kdDebug(1202) << k_funcinfo << endl; + + setComplete(); + emit m_pBrowserView->canceled( QString::null ); +} + +void KonqBaseListViewWidget::slotClear() +{ + //kdDebug(1202) << k_funcinfo << endl; + + m_activeItem = 0; + m_fileTip->setItem( 0 ); + delete m_selected; m_selected = 0; + m_pBrowserView->resetCount(); + m_pBrowserView->lstPendingMimeIconItems().clear(); + + viewport()->setUpdatesEnabled( false ); + setUpdatesEnabled( false ); + clear(); +} + +void KonqBaseListViewWidget::slotNewItems( const KFileItemList & entries ) +{ + //kdDebug(1202) << k_funcinfo << entries.count() << endl; + + for ( QPtrListIterator<KFileItem> kit ( entries ); kit.current(); ++kit ) + { + KonqListViewItem * tmp = new KonqListViewItem( this, *kit ); + if ( !m_itemFound && tmp->text(0) == m_itemToGoTo ) + { + setCurrentItem( tmp ); + m_itemFound = true; + } + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( tmp, true ); + } + } + if ( !(*kit)->isMimeTypeKnown() ) + m_pBrowserView->lstPendingMimeIconItems().append( tmp ); + } + m_pBrowserView->newItems( entries ); + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + slotUpdateBackground(); +} + +void KonqBaseListViewWidget::slotDeleteItem( KFileItem * _fileitem ) +{ + // new in 3.5.5 +#ifdef KPARTS_BROWSEREXTENSION_HAS_ITEMS_REMOVED + KFileItemList list; + list.append( _fileitem ); + emit m_pBrowserView->extension()->itemsRemoved( list ); +#else +#error "Your kdelibs doesn't have KParts::BrowserExtension::itemsRemoved, please update it to at least 3.5.5" +#endif + + iterator it = begin(); + for( ; it != end(); ++it ) + if ( (*it).item() == _fileitem ) + { + kdDebug(1202) << k_funcinfo << "removing " << _fileitem->url().url() << " from tree!" << endl; + + m_pBrowserView->deleteItem( _fileitem ); + m_pBrowserView->lstPendingMimeIconItems().remove( &(*it) ); + + if ( m_activeItem == &(*it) ) { + m_fileTip->setItem( 0 ); + m_activeItem = 0; + } + + delete &(*it); + // HACK HACK HACK: QListViewItem/KonqBaseListViewItem should + // take care and the source looks like it does; till the + // real bug is found, this fixes some crashes (malte) + emit selectionChanged(); + return; + } + + // This is needed for the case the root of the current view is deleted. + // I supposed slotUpdateBackground has to be called as well after an item + // was removed from a listview and was just forgotten previously (Brade). + // OK, but this code also gets activated when deleting a hidden file... (dfaure) + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + slotUpdateBackground(); +} + +void KonqBaseListViewWidget::slotRefreshItems( const KFileItemList & entries ) +{ + //kdDebug(1202) << k_funcinfo << endl; + + QPtrListIterator<KFileItem> kit ( entries ); + for ( ; kit.current(); ++kit ) + { + iterator it = begin(); + for ( ; it != end(); ++it ) + if ( (*it).item() == kit.current() ) + { + it->updateContents(); + break; + } + } + + reportItemCounts(); +} + +void KonqBaseListViewWidget::slotRedirection( const KURL & url ) +{ + kdDebug(1202) << k_funcinfo << url << endl; + + if ( (columns() < 1) || (url.protocol() != m_url.protocol()) ) + { + readProtocolConfig( url ); + createColumns(); + } + const QString prettyURL = url.pathOrURL(); + emit m_pBrowserView->extension()->setLocationBarURL( prettyURL ); + emit m_pBrowserView->setWindowCaption( prettyURL ); + m_pBrowserView->m_url = url; + m_url = url; +} + +KonqBaseListViewWidget::iterator& KonqBaseListViewWidget::iterator::operator++() +{ + if ( !m_p ) return *this; + KonqBaseListViewItem *i = (KonqBaseListViewItem *)m_p->firstChild(); + if ( i ) + { + m_p = i; + return *this; + } + i = (KonqBaseListViewItem *)m_p->nextSibling(); + if ( i ) + { + m_p = i; + return *this; + } + m_p = (KonqBaseListViewItem *)m_p->parent(); + + while ( m_p ) + { + if ( m_p->nextSibling() ) + break; + m_p = (KonqBaseListViewItem *)m_p->parent(); + } + + if ( m_p ) + m_p = (KonqBaseListViewItem *)m_p->nextSibling(); + + return *this; +} + +KonqBaseListViewWidget::iterator KonqBaseListViewWidget::iterator::operator++(int) +{ + KonqBaseListViewWidget::iterator it = *this; + if ( !m_p ) return it; + KonqBaseListViewItem *i = (KonqBaseListViewItem *)m_p->firstChild(); + if ( i ) + { + m_p = i; + return it; + } + i = (KonqBaseListViewItem *)m_p->nextSibling(); + if ( i ) + { + m_p = i; + return it; + } + m_p = (KonqBaseListViewItem *)m_p->parent(); + + while ( m_p ) + { + if ( m_p->nextSibling() ) + break; + m_p = (KonqBaseListViewItem *)m_p->parent(); + } + + if ( m_p ) + m_p = (KonqBaseListViewItem *)m_p->nextSibling(); + return it; +} + +void KonqBaseListViewWidget::paintEmptyArea( QPainter *p, const QRect &r ) +{ + const QPixmap *pm = viewport()->paletteBackgroundPixmap(); + + if (!pm || pm->isNull()) + p->fillRect(r, viewport()->backgroundColor()); + else + { + QRect devRect = p->xForm( r ); + int ax = (devRect.x() + contentsX()); + int ay = (devRect.y() + contentsY()); + /* kdDebug() << "KonqBaseListViewWidget::paintEmptyArea " + << r.x() << "," << r.y() << " " << r.width() << "x" << r.height() + << " drawing pixmap with offset " << ax << "," << ay + << endl;*/ + p->drawTiledPixmap(r, *pm, QPoint(ax, ay)); + } +} + +void KonqBaseListViewWidget::disableIcons( const KURL::List & lst ) +{ + iterator kit = begin(); + for( ; kit != end(); ++kit ) + { + bool bFound = false; + // Wow. This is ugly. Matching two lists together.... + // Some sorting to optimise this would be a good idea ? + for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it) + { + if ( (*kit).item()->url() == *it ) // *it is encoded already + { + bFound = true; + // maybe remove "it" from lst here ? + } + } + (*kit).setDisabled( bFound ); + } +} + +void KonqBaseListViewWidget::saveState( QDataStream & ds ) +{ + QString str; + if ( currentItem() ) + str = static_cast<KonqBaseListViewItem*>(currentItem())->item()->url().fileName(true); + ds << str << m_url; +} + +void KonqBaseListViewWidget::restoreState( QDataStream & ds ) +{ + m_restored = true; + + QString str; + KURL url; + ds >> str >> url; + if ( !str.isEmpty() ) + m_itemToGoTo = str; + + if ( columns() < 1 || url.protocol() != m_url.protocol() ) + { + readProtocolConfig( url ); + createColumns(); + } + m_url = url; + + m_bTopLevelComplete = false; + m_itemFound = false; +} + +void KonqBaseListViewWidget::slotUpdateBackground() +{ + if ( viewport()->paletteBackgroundPixmap() && !viewport()->paletteBackgroundPixmap()->isNull() ) + { + if ( !m_backgroundTimer ) + { + m_backgroundTimer = new QTimer( this ); + connect( m_backgroundTimer, SIGNAL( timeout() ), viewport(), SLOT( update() ) ); + } + else + m_backgroundTimer->stop(); + + m_backgroundTimer->start( 50, true ); + } +} + +bool KonqBaseListViewWidget::caseInsensitiveSort() const +{ + return m_pBrowserView->m_pProps->isCaseInsensitiveSort(); +} + +// based on isExecuteArea from klistview.cpp +int KonqBaseListViewWidget::executeArea( QListViewItem *_item ) +{ + if ( !_item ) + return 0; + + int width = treeStepSize() * ( _item->depth() + ( rootIsDecorated() ? 1 : 0 ) ); + width += itemMargin(); + int ca = AlignHorizontal_Mask & columnAlignment( 0 ); + if ( ca == AlignLeft || ca == AlignAuto ) + { + width += _item->width( fontMetrics(), this, 0 ); + if ( width > columnWidth( 0 ) ) + width = columnWidth( 0 ); + } + return width; +} + +#include "konq_listviewwidget.moc" diff --git a/konqueror/listview/konq_listviewwidget.h b/konqueror/listview/konq_listviewwidget.h new file mode 100644 index 000000000..bc4161862 --- /dev/null +++ b/konqueror/listview/konq_listviewwidget.h @@ -0,0 +1,270 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + 2004 Michael Brade <[email protected]> + + 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 __konq_listviewwidget_h__ +#define __konq_listviewwidget_h__ + +#include <qvaluelist.h> +#include <qvaluevector.h> + +#include <kurl.h> +#include <kfileitem.h> +#include <klistview.h> +#include <kparts/browserextension.h> +#include <konq_propsview.h> +#include "konq_listviewitems.h" + +namespace KIO { class Job; } + +class QCursor; +class QRect; +class KDirLister; +class KonqFMSettings; +class ListViewPropertiesExtension; +class KToggleAction; +class KonqListView; +class KonqFileTip; +class ListViewBrowserExtension; +class QTimer; +class QFocusEvent; +class QDragMoveEvent; +class QDragEnterEvent; +class QDragLeaveEvent; +class QDropEvent; +class QPaintEvent; +class QResizeEvent; +class QMouseEvent; + +class ColumnInfo +{ +public: + ColumnInfo(); + void setData( const QString& n, const QString& desktopName, int kioUds, + KToggleAction *someAction, int theWith = -1 ); + void setData( const QString& n, const QString& desktopName, int kioUds /* UDS_EXTRA */, + QVariant::Type type, KToggleAction *someAction, int theWith = -1 ); + int displayInColumn; + QString name; + QString desktopFileName; + int udsId; + QVariant::Type type; // only used if udsId == UDS_EXTRA + bool displayThisOne; + KToggleAction *toggleThisOne; + int width; +}; + +/** + * The tree view widget (based on KListView). + * Most of the functionality is here. + */ +class KonqBaseListViewWidget : public KListView +{ + friend class KonqBaseListViewItem; + friend class KonqListView; + friend class ListViewBrowserExtension; + + Q_OBJECT +public: + KonqBaseListViewWidget( KonqListView *parent, QWidget *parentWidget ); + virtual ~KonqBaseListViewWidget(); + unsigned int NumberOfAtoms; + + virtual void stop(); + const KURL& url(); + + struct iterator + { + KonqBaseListViewItem *m_p; + + iterator() : m_p( 0L ) { } + iterator( KonqBaseListViewItem *_b ) : m_p( _b ) { } + iterator( const iterator& _it ) : m_p( _it.m_p ) { } + + KonqBaseListViewItem& operator*() { return *m_p; } + KonqBaseListViewItem *operator->() { return m_p; } + bool operator==( const iterator& _it ) { return ( m_p == _it.m_p ); } + bool operator!=( const iterator& _it ) { return ( m_p != _it.m_p ); } + iterator& operator++(); + iterator operator++(int); + }; + iterator begin() { iterator it( (KonqBaseListViewItem *)firstChild() ); return it; } + iterator end() { iterator it; return it; } + + virtual bool openURL( const KURL &url ); + + void selectedItems( QPtrList<KonqBaseListViewItem> *_list ); + KFileItemList visibleFileItems(); + KFileItemList selectedFileItems(); + KURL::List selectedUrls( bool mostLocal = false ); + + /** @return the KonqListViewDir which handles the directory _url */ + //virtual KonqListViewDir *findDir ( const QString & _url ); + + /** + * @return the Properties instance for this view. Used by the items. + */ + KonqPropsView *props() const; + + //QPtrList<ColumnInfo> *columnConfigInfo() { return &confColumns; }; + QValueVector<ColumnInfo>& columnConfigInfo() { return confColumns; }; + QString sortedByColumn; + + virtual void setShowIcons( bool enable ) { m_showIcons = enable; } + virtual bool showIcons() { return m_showIcons; } + + void setItemFont( const QFont &f ) { m_itemFont = f; } + QFont itemFont() const { return m_itemFont; } + void setItemColor( const QColor &c ) { m_itemColor = c; } + QColor itemColor() const { return m_itemColor; } + int iconSize() const { return props()->iconSize(); } + + void setAscending( bool b ) { m_bAscending = b; } + bool ascending() const { return m_bAscending; } + bool caseInsensitiveSort() const; + + virtual void paintEmptyArea( QPainter *p, const QRect &r ); + + virtual void saveState( QDataStream & ); + virtual void restoreState( QDataStream & ); + + virtual void disableIcons( const KURL::List& lst ); + + KonqListView *m_pBrowserView; + KonqFMSettings *m_pSettings; + +signals: + void viewportAdjusted(); + +public slots: + //virtual void slotOnItem( KonqBaseListViewItem* _item ); + // The '2' was added to differentiate it from KListView::slotMouseButtonClicked() + void slotMouseButtonClicked2( int _button, QListViewItem *_item, const QPoint& pos, int ); + virtual void slotExecuted( QListViewItem *_item ); + void slotItemRenamed( QListViewItem *, const QString &, int ); + +protected slots: + void slotAutoScroll(); + + // from QListView + virtual void slotReturnPressed( QListViewItem *_item ); + virtual void slotCurrentChanged( QListViewItem *_item ) { slotOnItem( _item ); } + + // slots connected to the directory lister + virtual void slotStarted(); + virtual void slotCompleted(); + virtual void slotCanceled(); + virtual void slotClear(); + virtual void slotNewItems( const KFileItemList & ); + virtual void slotDeleteItem( KFileItem * ); + virtual void slotRefreshItems( const KFileItemList & ); + virtual void slotRedirection( const KURL & ); + void slotPopupMenu( QListViewItem *, const QPoint&, int ); + + // forces a repaint on column size changes / branch expansion + // when there is a background pixmap + void slotUpdateBackground(); + + //Notifies the browser view of the currently selected items + void slotSelectionChanged(); + virtual void reportItemCounts(); + +protected: + //creates the listview columns according to confColumns + virtual void createColumns(); + //reads the configuration for the columns of the current + //protocol, it is called when the protocol changes + //it checks/unchecks the menu items and sets confColumns + void readProtocolConfig( const KURL& url ); + //calls updateContents of every ListViewItem, called after + //the columns changed + void updateListContents(); + + //this is called in the constructor, so virtual would be nonsense + void initConfig(); + + virtual void startDrag(); + virtual void viewportDragMoveEvent( QDragMoveEvent *_ev ); + virtual void viewportDragEnterEvent( QDragEnterEvent *_ev ); + virtual void viewportDragLeaveEvent( QDragLeaveEvent *_ev ); + virtual void viewportDropEvent( QDropEvent *_ev ); + virtual void viewportPaintEvent( QPaintEvent *e ); + virtual void viewportResizeEvent( QResizeEvent *e ); + + virtual void drawRubber(); + virtual void contentsMousePressEvent( QMouseEvent *e ); + virtual void contentsMouseReleaseEvent( QMouseEvent *e ); + virtual void contentsMouseMoveEvent( QMouseEvent *e ); + virtual void contentsWheelEvent( QWheelEvent * e ); + + virtual void leaveEvent( QEvent *e ); + + /** Common method for slotCompleted and slotCanceled */ + virtual void setComplete(); + + //the second parameter is set to true when the menu shortcut is pressed, + //so the position of the mouse pointer doesn't matter when using keyboard, aleXXX + virtual void popupMenu( const QPoint& _global, bool alwaysForSelectedFiles = false ); + + //this one is called only by KListView, and this is friend anyways (Alex) + //KDirLister *dirLister() const { return m_dirLister; } + +protected: + int executeArea( QListViewItem *_item ); + + /** The directory lister for this URL */ + KDirLister *m_dirLister; + + //QPtrList<ColumnInfo> confColumns; + // IMO there is really no need for an advanced data structure + //we have a fixed number of members, + //it consumes less memory and access should be faster (Alex) + // This might not be the case for ever... we should introduce custom fields in kio (David) + QValueVector<ColumnInfo> confColumns; + + KonqBaseListViewItem *m_dragOverItem; + KonqBaseListViewItem *m_activeItem; + QPtrList<KonqBaseListViewItem> *m_selected; + QTimer *m_scrollTimer; + + QFont m_itemFont; + QColor m_itemColor; + + QRect *m_rubber; + + bool m_bTopLevelComplete:1; + bool m_showIcons:1; + bool m_bCaseInsensitive:1; + bool m_bUpdateContentsPosAfterListing:1; + bool m_bAscending:1; + bool m_itemFound:1; + bool m_restored:1; + + int m_filenameColumn; + int m_filenameColumnWidth; + + KURL m_url; + + QString m_itemToGoTo; + QStringList m_itemsToSelect; + QTimer *m_backgroundTimer; + + KonqFileTip *m_fileTip; +}; + +#endif diff --git a/konqueror/listview/konq_textview.desktop b/konqueror/listview/konq_textview.desktop new file mode 100644 index 000000000..f5d4e5c98 --- /dev/null +++ b/konqueror/listview/konq_textview.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Type=Service +Name=Text View +Name[af]=Teks Besigtig +Name[ar]=عرض نصي +Name[az]=Mətn Görünüşü +Name[be]=Тэкст +Name[bg]=Текстов преглед +Name[bn]=টেক্সট ভিউ +Name[br]=Gwel skrid +Name[bs]=Tekstualni pogled +Name[ca]=Vista de text +Name[cs]=Textový pohled +Name[csb]=Tekstowi wëzdrzatk +Name[cy]=Golwg Testun +Name[da]=Tekstvisning +Name[de]=Textansicht +Name[el]=Προβολή κειμένου +Name[eo]=Tekstrigardo +Name[es]=Vista de texto +Name[et]=Vaade tekstina +Name[eu]=Testu ikuspegia +Name[fa]=متننما +Name[fi]=Tekstinäkymä +Name[fr]=Affichage de Texte +Name[fy]=Tekstwerjefte +Name[ga]=Amharc Téacs +Name[gl]=Vista de Texto +Name[he]=תצוגת טקסט +Name[hi]=पाठ दृश्य +Name[hr]=Tekstualni prikaz +Name[hu]=Szöveges +Name[id]=Tampilan Teks +Name[is]=Textasýn +Name[it]=Vista testuale +Name[ja]=テキストビュー +Name[ka]=ტექსტის სახით +Name[kk]=Жай мәтін тізім +Name[km]=ទិដ្ឋភាពអត្ថបទ +Name[ko]=VideoText 뷰어 +Name[lo]=ມຸມມອງຂໍ້ຄວາມ +Name[lt]=Rodyti tekstą +Name[lv]=Teksta Skatījums +Name[mk]=Текстуален преглед +Name[mn]=Текстээр харах +Name[ms]=Paparan Teks +Name[mt]=Uri Kliem biss +Name[nb]=Tekstvisning +Name[nds]=Textansicht +Name[ne]=पाठ दृश्य +Name[nl]=Tekstweergave +Name[nn]=Tekstvising +Name[nso]=Pono ya Sengwalwana +Name[pa]=ਪਾਠ ਝਲਕ +Name[pl]=Widok tekstowy +Name[pt]=Vista em Texto +Name[pt_BR]=Visão Texto +Name[ro]=Vizualizare text +Name[ru]=В виде текста +Name[rw]=Igaragaza Umwandiko +Name[se]=Teakstačájeheapmi +Name[sk]=Textový pohľad +Name[sl]=Besedilni pogled +Name[sr]=Текстуални приказ +Name[sr@Latn]=Tekstualni prikaz +Name[sv]=Textvy +Name[ta]=உரை காட்சி +Name[te]=వచన వీక్షణం +Name[tg]=Ба намуди матн +Name[th]=มุมมองแบบข้อความ +Name[tr]=Metin Görünümü +Name[tt]=Mätenle Küreneş +Name[uk]=Текстовий вигляд +Name[uz]=Matn koʻrinishida +Name[uz@cyrillic]=Матн кўринишида +Name[ven]=Mbonalelo ya Manwalwa +Name[vi]=Xem kiểu Văn bản +Name[wa]=Vey e môde tecse +Name[xh]=Imboniselo Yombhalo +Name[zh_CN]=文本视图 +Name[zh_TW]=文字檢視 +Name[zu]=Umbukiso wombhalo +MimeType=inode/directory +ServiceTypes=Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=TextView +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_text +InitialPreference=6 diff --git a/konqueror/listview/konq_textview.rc b/konqueror/listview/konq_textview.rc new file mode 100644 index 000000000..612deb5cb --- /dev/null +++ b/konqueror/listview/konq_textview.rc @@ -0,0 +1,35 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqTextView" version="5"> +<MenuBar> + <Menu name="edit"><text>&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>&View</text> + <Action name="show_dot" /> + <Action name="sort_caseinsensitive"/> + <Menu name="listview_show"><text>Show Details</text> + <TearOffHandle /> + <Action name="show_size"/> + <Action name="show_time"/> + <Action name="show_type"/> + <Action name="show_mimetype"/> + <Action name="show_url"/> + <Action name="show_access_time"/> + <Action name="show_creation_time"/> + <Action name="show_permissions"/> + <Action name="show_owner"/> + <Action name="show_group"/> + <Action name="show_link_dest"/> + </Menu> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/konqueror/listview/konq_textviewitem.cc b/konqueror/listview/konq_textviewitem.cc new file mode 100644 index 000000000..71d1de833 --- /dev/null +++ b/konqueror/listview/konq_textviewitem.cc @@ -0,0 +1,232 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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_textviewitem.h" +#include "konq_settings.h" + +#include <assert.h> +#include <stdio.h> +#include <kglobal.h> + +int KonqTextViewItem::compare( QListViewItem *item, int col, bool ascending ) const +{ + if (col==1) + return KonqBaseListViewItem::compare(item, 0, ascending); + return KonqBaseListViewItem::compare(item, col, ascending); +} + +/*QString KonqTextViewItem::key( int _column, bool asc) const +{ + if (_column==1) return key(0,asc); + QString tmp = QString::number( sortChar ); + //check if it is a time column + if (_column>1) + { + KonqTextViewWidget* lv = static_cast<KonqTextViewWidget *>(listView()); + for (unsigned int i=0; i<lv->NumberOfAtoms; i++) + { + ColumnInfo *cInfo=&lv->columnConfigInfo()[i]; + if (_column==cInfo->displayInColumn) + { + if ((cInfo->udsId==KIO::UDS_MODIFICATION_TIME) + || (cInfo->udsId==KIO::UDS_ACCESS_TIME) + || (cInfo->udsId==KIO::UDS_CREATION_TIME)) + { + tmp += QString::number( m_fileitem->time(cInfo->udsId) ).rightJustify( 14, '0' ); + return tmp; + } + else if (cInfo->udsId==KIO::UDS_SIZE) + { + tmp += KIO::number( m_fileitem->size() ).rightJustify( 20, '0' ); + return tmp; + } + else break; + + }; + }; + }; + tmp+=text(_column); + return tmp; +}*/ + +void KonqTextViewItem::updateContents() +{ + QString tmp; + KIO::filesize_t size=m_fileitem->size(); + mode_t m=m_fileitem->mode(); + + // The order is: .dir (0), dir (1), .file (2), file (3) + sortChar = S_ISDIR( m_fileitem->mode() ) ? 1 : 3; + if ( m_fileitem->text()[0] == '.' ) + --sortChar; + + if (m_fileitem->isLink()) + { + if (S_ISDIR(m)) + { + type=KTVI_DIRLINK; + tmp="~"; + } + else if ((S_ISREG(m)) || (S_ISCHR(m)) || (S_ISBLK(m)) || (S_ISSOCK(m)) || (S_ISFIFO(m))) + { + tmp="@"; + type=KTVI_REGULARLINK; + } + else + { + tmp="!"; + type=KTVI_UNKNOWN; + size=0; + }; + } + else if (S_ISREG(m)) + { + if ((m_fileitem->permissions() & (S_IXUSR|S_IXGRP|S_IXOTH)) !=0 ) + { + tmp="*"; + type=KTVI_EXEC; + } + else + { + tmp=""; + type=KTVI_REGULAR; + }; + } + else if (S_ISDIR(m)) + { + type=KTVI_DIR; + tmp="/"; + } + else if (S_ISCHR(m)) + { + type=KTVI_CHARDEV; + tmp="-"; + } + else if (S_ISBLK(m)) + { + type=KTVI_BLOCKDEV; + tmp="+"; + } + else if (S_ISSOCK(m)) + { + type=KTVI_SOCKET; + tmp="="; + } + else if (S_ISFIFO(m)) + { + type=KTVI_FIFO; + tmp=">"; + } + else + { + tmp="!"; + type=KTVI_UNKNOWN; + size=0; + }; + setText(1,tmp); + setText(0,m_fileitem->text()); + //now we have the first two columns, so let's do the rest + KonqTextViewWidget* lv = static_cast<KonqTextViewWidget *>(listView()); + + for (unsigned int i=0; i<lv->NumberOfAtoms; i++) + { + ColumnInfo *tmpColumn=&lv->confColumns[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case KIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case KIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case KIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case KIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case KIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case KIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case KIO::UDS_SIZE: + if ( static_cast<KonqBaseListViewWidget *>(listView())->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatNumber(size, 0)+" "); + else + setText(tmpColumn->displayInColumn,KIO::convertSize(size)+" "); + break; + case KIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + for( KIO::UDSEntry::ConstIterator it = m_fileitem->entry().begin(); it != m_fileitem->entry().end(); it++ ) + { + if ((*it).m_uds==(unsigned int)tmpColumn->udsId) + { + QDateTime dt; + dt.setTime_t((time_t) (*it).m_long); + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatDateTime(dt)); + break; + }; + + }; + break; + default: + break; + }; + }; + }; +} + +void KonqTextViewItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + QColorGroup cg( _cg ); + cg.setColor(QColorGroup::Text, static_cast<KonqTextViewWidget *>(listView())->colors[type]); + // Don't do that! Keep things readable whatever the selection background color is +// cg.setColor(QColorGroup::HighlightedText, static_cast<KonqTextViewWidget *>(listView())->highlight[type]); +// cg.setColor(QColorGroup::Highlight, Qt::darkGray); + + KListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +/*void KonqTextViewItem::paintFocus( QPainter *_p, const QColorGroup &_cg, const QRect &_r ) +{ + listView()->style().drawFocusRect( _p, _r, _cg, + isSelected() ? &_cg.highlight() : &_cg.base(), isSelected() ); + + QPixmap pix( _r.width(), _r.height() ); + bitBlt( &pix, 0, 0, _p->device(), _r.left(), _r.top(), _r.width(), _r.height() ); + QImage im = pix.convertToImage(); + im = KImageEffect::fade( im, 0.25, Qt::black ); + _p->drawImage( _r.topLeft(), im ); +}*/ + +void KonqTextViewItem::setup() +{ + widthChanged(); + int h(listView()->fontMetrics().height()); + if ( h % 2 > 0 ) h++; + setHeight(h); +} diff --git a/konqueror/listview/konq_textviewitem.h b/konqueror/listview/konq_textviewitem.h new file mode 100644 index 000000000..413016bea --- /dev/null +++ b/konqueror/listview/konq_textviewitem.h @@ -0,0 +1,75 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 __konq_textviewitem_h__ +#define __konq_textviewitem_h__ + +#include <qlistview.h> +#include <qstring.h> +#include <kio/global.h> +#include <klocale.h> +#include "konq_listviewitems.h" +#include "konq_textviewwidget.h" + +class KFileItem; +class QPainter; + +#define KTVI_REGULAR 0 +#define KTVI_REGULARLINK 1 +#define KTVI_EXEC 2 +#define KTVI_DIR 3 +#define KTVI_DIRLINK 4 +#define KTVI_BADLINK 5 +#define KTVI_SOCKET 6 +#define KTVI_CHARDEV 7 +#define KTVI_BLOCKDEV 8 +#define KTVI_FIFO 9 +#define KTVI_UNKNOWN 10 + + +class KonqTextViewItem : public KonqBaseListViewItem +{ + public: + /** + * Create an item in the text toplevel representing a file + * @param _parent the parent widget, the text view + * @param _fileitem the file item created by KDirLister + */ + KonqTextViewItem( KonqTextViewWidget *_parent, KFileItem* _fileitem ); + virtual ~KonqTextViewItem() {/*cerr<<"~KonqTextViewItem: "<<text(1)<<endl;*/ }; + virtual int compare( QListViewItem* i, int col, bool ascending ) const; +// virtual QString key( int _column, bool asc) const; + /** Call this before destroying the text view (decreases reference count + * on the view)*/ + virtual void paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ); +// virtual void paintFocus( QPainter *_painter, const QColorGroup & _cg, const QRect & r ); + virtual void updateContents(); + + protected: + virtual void setup(); + int type; +}; + +inline KonqTextViewItem::KonqTextViewItem( KonqTextViewWidget *_parent, KFileItem* _fileitem ) +:KonqBaseListViewItem( _parent,_fileitem ) +{ + updateContents(); +} + +#endif diff --git a/konqueror/listview/konq_textviewwidget.cc b/konqueror/listview/konq_textviewwidget.cc new file mode 100644 index 000000000..96c498297 --- /dev/null +++ b/konqueror/listview/konq_textviewwidget.cc @@ -0,0 +1,223 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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_listview.h" +#include "konq_textviewitem.h" + +#include <qheader.h> + +#include <kdebug.h> +#include <kdirlister.h> + +#include <stdlib.h> +#include <assert.h> + + +KonqTextViewWidget::KonqTextViewWidget( KonqListView *parent, QWidget *parentWidget ) +:KonqBaseListViewWidget(parent,parentWidget) +{ + kdDebug(1202) << "+KonqTextViewWidget" << endl; + m_filenameColumn=1; + + // David: This breaks dropping things towards the current directory + // using the columns != Name. + // I know, but I want to have it this way and I use it all the time. + // If I want to have free space, I disable some columns. + // If people don't like it, they can use a different view type. Alex + setAllColumnsShowFocus(TRUE); + setRootIsDecorated(false); + + colors[KTVI_REGULAR]=Qt::black; + colors[KTVI_EXEC]=QColor(0,170,0); + colors[KTVI_REGULARLINK]=Qt::black; + colors[KTVI_DIR]=Qt::black; + colors[KTVI_DIRLINK]=Qt::black; + colors[KTVI_BADLINK]=Qt::red; + colors[KTVI_SOCKET]=Qt::magenta; + colors[KTVI_FIFO]=Qt::magenta; + colors[KTVI_UNKNOWN]=Qt::red; + colors[KTVI_CHARDEV]=Qt::blue; + colors[KTVI_BLOCKDEV]=Qt::blue; + + m_showIcons=FALSE; +} + +KonqTextViewWidget::~KonqTextViewWidget() +{} + +void KonqTextViewWidget::createColumns() +{ + if (columns()<2) + { + addColumn( i18n("Name"), m_filenameColumnWidth ); + addColumn( " ", fontMetrics().width("@") + 2 ); + setColumnAlignment( 1, AlignRight ); + //this way the column with the name has the index 0 and + //so the "jump to filename beginning with this character" works + header()->moveSection( 0, 2 ); + } + KonqBaseListViewWidget::createColumns(); +} + +void KonqTextViewWidget::slotNewItems( const KFileItemList & entries ) +{ + //kdDebug(1202) << k_funcinfo << entries.count() << endl; + + for ( QPtrListIterator<KFileItem> kit ( entries ); kit.current(); ++kit ) + { + KonqTextViewItem *tmp = new KonqTextViewItem( this, *kit ); + if ( !m_itemFound && tmp->text(0) == m_itemToGoTo ) + { + setCurrentItem( tmp ); + m_itemFound = true; + } + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( tmp, true ); + } + } + + } + + m_pBrowserView->newItems( entries ); + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + slotUpdateBackground(); +} + +void KonqTextViewWidget::setComplete() +{ + kdDebug(1202) << k_funcinfo << "Update Contents Pos: " + << m_bUpdateContentsPosAfterListing << endl; + + m_bTopLevelComplete = true; + + // Alex: this flag is set when we are just finishing a voluntary listing, + // so do the go-to-item thing only under here. When we update the + // current directory automatically (e.g. after a file has been deleted), + // we don't want to go to the first item ! (David) + if ( m_bUpdateContentsPosAfterListing ) + { + m_bUpdateContentsPosAfterListing = false; + + if ( !m_itemFound ) + setCurrentItem( firstChild() ); + + if ( !m_restored && !m_pBrowserView->extension()->urlArgs().reload ) + ensureItemVisible( currentItem() ); + else + setContentsPos( m_pBrowserView->extension()->urlArgs().xOffset, + m_pBrowserView->extension()->urlArgs().yOffset ); + + activateAutomaticSelection(); + emit selectionChanged(); + } + + m_itemToGoTo = ""; + m_restored = false; + + // Show "cut" icons as such + m_pBrowserView->slotClipboardDataChanged(); + // Show totals + slotOnViewport(); + + if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } +} + +bool KonqTextViewWidget::isExecuteArea( const QPoint& point ) +{ + if (!itemAt( point ) ) + return false; + int x=point.x(); + + int offset = 0; + int width = columnWidth( 0 ); + int pos = header()->mapToIndex( 0 ); + + for ( int index = 0; index < pos; index++ ) + offset += columnWidth( header()->mapToSection( index ) ); + + return ( x > offset && x < ( offset + width ) ); +} + +/*void KonqTextViewWidget::viewportDragMoveEvent( QDragMoveEvent *_ev ) +{ + KonqBaseListViewItem *item = + isNameColumn( _ev->pos() ) ? (KonqBaseListViewItem*)itemAt( _ev->pos() ) : 0L; + + if ( !item ) + { + if ( m_dragOverItem ) + setSelected( m_dragOverItem, false ); + _ev->accept(); + return; + } + + if ( m_dragOverItem == item ) + return; // No change + + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + + if ( item->item()->acceptsDrops() ) + { + _ev->accept(); + setSelected( item, true ); + m_dragOverItem = item; + } + else + { + _ev->ignore(); + m_dragOverItem = 0L; + } +} + +void KonqTextViewWidget::viewportDropEvent( QDropEvent *ev ) +{ + if ( m_dirLister->url().isEmpty() ) + return; + kdDebug() << "KonqTextViewWidget::viewportDropEvent" << endl; + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + m_dragOverItem = 0L; + + ev->accept(); + + // We dropped on an item only if we dropped on the Name column. + KonqBaseListViewItem *item = + isNameColumn( ev->pos() ) ? (KonqBaseListViewItem*)itemAt( ev->pos() ) : 0; + + KFileItem * destItem = (item) ? item->item() : m_dirLister->rootItem(); // may be 0 + KonqOperations::doDrop( destItem, destItem ? destItem->url() : url(), ev, this ); +}*/ + + +#include "konq_textviewwidget.moc" diff --git a/konqueror/listview/konq_textviewwidget.h b/konqueror/listview/konq_textviewwidget.h new file mode 100644 index 000000000..f799286ff --- /dev/null +++ b/konqueror/listview/konq_textviewwidget.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 __konq_textviewwidget_h__ +#define __konq_textviewwidget_h__ + +#include "konq_listviewwidget.h" + +#include <kurl.h> + +class KonqListView; +class KonqTextViewItem; + +/** + * The text view + */ +class KonqTextViewWidget : public KonqBaseListViewWidget +{ + friend class KonqTextViewItem; + Q_OBJECT + public: + KonqTextViewWidget( KonqListView *parent, QWidget *parentWidget ); + ~KonqTextViewWidget(); + virtual bool isExecuteArea( const QPoint& point ); + + protected slots: + // slots connected to the directory lister + virtual void setComplete(); + virtual void slotNewItems( const KFileItemList & ); + protected: +// bool isNameColumn(const QPoint& point ); +// virtual void viewportDragMoveEvent( QDragMoveEvent *_ev ); +// virtual void viewportDropEvent( QDropEvent *ev ); + virtual void createColumns(); + + QColor colors[11]; +}; + +#endif diff --git a/konqueror/listview/konq_treeview.desktop b/konqueror/listview/konq_treeview.desktop new file mode 100644 index 000000000..3fcce32db --- /dev/null +++ b/konqueror/listview/konq_treeview.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Type=Service +Name=Tree View +Name[af]=Boom Besigtig +Name[ar]=عرض شجري +Name[az]=Ağaç Görünüşü +Name[be]=Дрэва +Name[bg]=Дървовиден преглед +Name[bn]=ট্রি ভিউ +Name[br]=Gwel gwezenn +Name[bs]=Pogled stabla +Name[ca]=Vista d'arbre +Name[cs]=Stromový pohled +Name[csb]=Wëzdrzatk drzéwiã +Name[cy]=Golwg Coeden +Name[da]=Trævisning +Name[de]=Baumansicht +Name[el]=Προβολή δέντρου +Name[eo]=Arba rigardo +Name[es]=Vista en árbol +Name[et]=Vaade puuna +Name[eu]=Zuhaitz erako ikuspegia +Name[fa]=درختنما +Name[fi]=Puunäkymä +Name[fr]=Affichage en arborescence +Name[fy]=Beamstruktuerwerjefte +Name[ga]=Amharc Crainn +Name[gl]=Vista de Árbore +Name[he]=תצוגת עץ +Name[hi]=ट्री दृश्य +Name[hr]=Prikaz stabla +Name[hu]=Fastruktúra +Name[id]=Tampilan Pohon +Name[is]=Trjáasýn +Name[it]=Vista ad albero +Name[ja]=ツリービュー +Name[ka]=ხის სახით +Name[kk]=Бұтақ түрінде +Name[km]=ទិដ្ឋភាពមែកធាង +Name[lo]=ມຸມມອງແບບລາຍການຕົ້ນໄມ້ +Name[lt]=Rodyti medį +Name[lv]=Koka Skatījums +Name[mk]=Преглед со стебло +Name[mn]=Модоор харах +Name[ms]=Paparan Pepohon +Name[mt]=Uri Friegħi +Name[nb]=Trevisning +Name[nds]=Boomansicht +Name[ne]=ट्रि दृश्य +Name[nl]=Boomstructuurweergave +Name[nn]=Trevising +Name[nso]=Pono ya Mohlare +Name[pa]=ਲੜੀ ਝਲਕ +Name[pl]=Widok drzewa +Name[pt]=Vista em Árvore +Name[pt_BR]=Visão em Árvore +Name[ro]=Vizualizare arborescentă +Name[ru]=В виде дерева +Name[rw]=Igaragaza Igiti +Name[se]=Muorračájeheapmi +Name[sk]=Stromová štruktúra +Name[sl]=Drevesni pogled +Name[sr]=Приказ стабла +Name[sr@Latn]=Prikaz stabla +Name[sv]=Trädvy +Name[ta]=மரக் காட்சி +Name[te]=ట్రీ వీక్షణం +Name[tg]=Ба намуди дарахт +Name[th]=มุมมองแบบรายการต้นไม้ +Name[tr]=Ağaç Görünümü +Name[tt]=Ağaçlı Küreneş +Name[uk]=Вигляд структури каталогів +Name[uz]=Daraxt koʻrinishida +Name[uz@cyrillic]=Дарахт кўринишида +Name[ven]=Mbonalelo ya Muri +Name[vi]=Xem kiểu Cây +Name[wa]=Vey come èn åbe +Name[xh]=Imboniselo Yomthi +Name[zh_CN]=树视图 +Name[zh_TW]=樹狀瀏覽 +Name[zu]=Umbukiso Wesihlahla +MimeType=inode/directory +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=MixedTree +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-HierarchicalView=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_tree +InitialPreference=8 diff --git a/konqueror/listview/konq_treeview.rc b/konqueror/listview/konq_treeview.rc new file mode 100644 index 000000000..7f8981779 --- /dev/null +++ b/konqueror/listview/konq_treeview.rc @@ -0,0 +1,52 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqTreeView" version="10"> +<MenuBar> + <Menu name="edit"><text>&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>&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> + <Separator/> + <Action name="show_dot"/> + <Action name="sort_caseinsensitive"/> + <!--<Action name="sort_directoriesfirst" /> TODO --> + <Menu name="listview_show"><text>Show Details</text> + <TearOffHandle /> + <Action name="show_size"/> + <Action name="show_type"/> + <Action name="show_mimetype"/> + <Action name="show_url"/> + <Action name="show_time"/> + <Action name="show_access_time"/> + <Action name="show_creation_time"/> + <Action name="show_permissions"/> + <Action name="show_owner"/> + <Action name="show_group"/> + <Action name="show_link_dest"/> + </Menu> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar"><text>Treeview Toolbar</text> + <Separator/> + <Action name="incIconSize" /> + <Action name="decIconSize" /> +</ToolBar> +</kpartgui> diff --git a/konqueror/listview/konq_treeviewitem.cc b/konqueror/listview/konq_treeviewitem.cc new file mode 100644 index 000000000..09b9d941b --- /dev/null +++ b/konqueror/listview/konq_treeviewitem.cc @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + 2001, 2002, 2004 Michael Brade <[email protected]> + + 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_treeviewwidget.h" +#include "konq_listview.h" + + +KonqListViewDir::KonqListViewDir( KonqTreeViewWidget *_parent, KFileItem* _fileitem ) + : KonqListViewItem( _parent, _fileitem ) +{ + setExpandable( true ); + m_bComplete = false; +} + +KonqListViewDir::KonqListViewDir( KonqTreeViewWidget *_treeview, KonqListViewDir *_parent, KFileItem *_fileitem ) + : KonqListViewItem( _treeview, _parent, _fileitem ) +{ + setExpandable( true ); + m_bComplete = false; +} + +void KonqListViewDir::setOpen( bool _open ) +{ + open( _open, false ); +} + +void KonqListViewDir::open( bool _open, bool _reload ) +{ + if ( _open != isOpen() || _reload ) + { + KonqTreeViewWidget *treeView = static_cast<KonqTreeViewWidget *>(m_pListViewWidget); + + if ( _open ) + { + if ( !m_bComplete || _reload ) // complete it before opening + treeView->openSubFolder( this, _reload ); + else + { + // we need to add the items to the counts for the statusbar + KFileItemList lst; + lst.setAutoDelete( false ); + + QListViewItem* it = firstChild(); + while ( it ) + { + lst.append( static_cast<KonqListViewItem*>(it)->item() ); + it = it->nextSibling(); + } + + // tell the view about the new items to count + treeView->m_pBrowserView->newItems( lst ); + } + } + else + { + treeView->stopListingSubFolder( this ); + + QListViewItem* it = firstChild(); + while ( it ) + { + // unselect the items in the closed folder + treeView->setSelected( it, false ); + // delete the item from the counts for the statusbar + KFileItem* item = static_cast<KonqListViewItem*>(it)->item(); + treeView->m_pBrowserView->deleteItem( item ); + it = it->nextSibling(); + } + } + + QListViewItem::setOpen( _open ); + treeView->slotOnViewport(); + } +} + +QString KonqListViewDir::url( int _trailing ) +{ + return item()->url().url( _trailing ); +} + diff --git a/konqueror/listview/konq_treeviewitem.h b/konqueror/listview/konq_treeviewitem.h new file mode 100644 index 000000000..5341a811a --- /dev/null +++ b/konqueror/listview/konq_treeviewitem.h @@ -0,0 +1,79 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 __konq_treeviewitem_h__ +#define __konq_treeviewitem_h__ + +#include <qstring.h> +#include "konq_listviewitems.h" + +class KFileItem; +class KonqTreeViewWidget; + +/** + * An item specialized for directories + */ +class KonqListViewDir : public KonqListViewItem +{ +public: + /** + * Create an item in the tree toplevel representing a directory + * @param _parent the parent widget, the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewDir( KonqTreeViewWidget *_parent, KFileItem *_fileitem ); + + /** + * Create an item representing a directory, inside a directory + * @param _treeview the parent tree view + * @param _parent the parent widget, a directory item in the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewDir( KonqTreeViewWidget *_treeview, KonqListViewDir *_parent, KFileItem *_fileitem ); + + /** + * Called when user opens the directory (inherited from QListViewItem). + * Just calls @ref #open(). + */ + virtual void setOpen( bool _open ); + + /** + * Called by setOpen, called when opening the directoy via restoreState and called + * when the user presses "Reload". + * Checks whether its contents are known (@see #setComplete) or whether + * to reload the directory. + */ + void open( bool _open, bool _reload ); + + /** + * Set to true when contents are completely known (one sublevel only). + */ + virtual void setComplete( bool _b ) { m_bComplete = _b; } + + /** + * URL of this directory + * @param _trailing set to true for a trailing slash (see KURL) + */ + QString url( int _trailing ); + +protected: + bool m_bComplete; +}; + +#endif diff --git a/konqueror/listview/konq_treeviewwidget.cc b/konqueror/listview/konq_treeviewwidget.cc new file mode 100644 index 000000000..67844fa3d --- /dev/null +++ b/konqueror/listview/konq_treeviewwidget.cc @@ -0,0 +1,307 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + 2001, 2002, 2004 Michael Brade <[email protected]> + + 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_listview.h" +#include "konq_treeviewwidget.h" + +#include <kdirlister.h> +#include <kdebug.h> + +template class QDict<KonqListViewDir>; + + +KonqTreeViewWidget::KonqTreeViewWidget( KonqListView *parent, QWidget *parentWidget) + : KonqBaseListViewWidget( parent, parentWidget ) +{ + kdDebug(1202) << "+KonqTreeViewWidget" << endl; + + setRootIsDecorated( true ); + setTreeStepSize( 20 ); + + connect( m_dirLister, SIGNAL( completed( const KURL & ) ), + this, SLOT( slotCompleted( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( clear( const KURL & ) ), + this, SLOT( slotClear( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( redirection( const KURL &, const KURL & ) ), + this, SLOT( slotRedirection( const KURL &, const KURL & ) ) ); +} + +KonqTreeViewWidget::~KonqTreeViewWidget() +{ + kdDebug(1202) << "-KonqTreeViewWidget" << endl; + + // Remove all items + clear(); + // Clear dict + m_dictSubDirs.clear(); +} + +bool KonqTreeViewWidget::openURL( const KURL &url ) +{ + //kdDebug(1202) << k_funcinfo << url.prettyURL() << endl; + + if ( m_pBrowserView->extension()->urlArgs().reload ) + { + QDictIterator<KonqListViewDir> it( m_dictSubDirs ); + for (; it.current(); ++it ) + if ( it.current()->isOpen() ) + m_urlsToReload.append( it.current()->url( -1 ) ); + + // Someone could press reload while the listing is still in progess + // -> move the items that are not opened yet to m_urlsToReload. + // We don't need to check for doubled items since remove() removes + // all occurrences. + m_urlsToReload += m_urlsToOpen; + m_urlsToOpen.clear(); + } + + return KonqBaseListViewWidget::openURL( url ); +} + +void KonqTreeViewWidget::saveState( QDataStream &stream ) +{ + QStringList openDirList; + + QDictIterator<KonqListViewDir> it( m_dictSubDirs ); + for (; it.current(); ++it ) + { + if ( it.current()->isOpen() ) + openDirList.append( it.current()->url( -1 ) ); + } + + stream << openDirList; + KonqBaseListViewWidget::saveState( stream ); +} + +void KonqTreeViewWidget::restoreState( QDataStream &stream ) +{ + stream >> m_urlsToOpen; + KonqBaseListViewWidget::restoreState( stream ); +} + +void KonqTreeViewWidget::slotCompleted() +{ + // This is necessary because after reloading it could happen that a + // previously opened subdirectory was deleted and this would still + // be queued for opening. + m_urlsToReload.clear(); + m_urlsToOpen.clear(); + + KonqBaseListViewWidget::slotCompleted(); +} + +void KonqTreeViewWidget::slotCompleted( const KURL & _url ) +{ + // do nothing if the view itself is finished + if ( m_url.equals( _url, true ) ) + return; + + KonqListViewDir *dir = m_dictSubDirs[ _url.url(-1) ]; + if ( dir ) + dir->setComplete( true ); + else + kdWarning() << "KonqTreeViewWidget::slotCompleted : dir " << _url.url(-1) << " not found in dict!" << endl; + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } +} + +void KonqTreeViewWidget::slotClear() +{ + kdDebug(1202) << k_funcinfo << endl; + + m_dictSubDirs.clear(); + KonqBaseListViewWidget::slotClear(); +} + +void KonqTreeViewWidget::slotClear( const KURL & _url ) +{ + // normally this means we have to delete only the contents of directory _url + // but we are allowed to delete the subdirs as well since the opening of + // subdirs happens level per level. If a subdir is deleted with delete, all + // its children will be deleted by Qt immediately! + + kdDebug(1202) << k_funcinfo << _url << endl; + + KonqListViewDir *item = m_dictSubDirs[_url.url(-1)]; + if ( item ) + { + // search all subdirs of _url (item) + QDictIterator<KonqListViewDir> it( m_dictSubDirs ); + while ( it.current() ) + { + if ( !_url.equals( it.currentKey(), true ) + && _url.isParentOf( it.currentKey() ) ) + { + m_urlsToOpen.remove( it.currentKey() ); + m_urlsToReload.remove( it.currentKey() ); + m_dictSubDirs.remove( it.currentKey() ); // do last, it changes it.currentKey()!! + } + else + ++it; + } + + // Remark: This code works only if we have exactly one tree which is the + // case for Konqy's treeview. It will break if m_dictSubDirs contains two + // subdirectories where only one of them will have its items deleted by + // the following code. + + // delete all child items, their fileitems are no longer valid + QListViewItem *child; + while ( (child = item->firstChild()) ) + delete child; + + // only if we really deleted something update the statusbar + reportItemCounts(); + } +} + +void KonqTreeViewWidget::slotRedirection( const KURL &oldUrl, const KURL &newUrl ) +{ + kdDebug(1202) << k_funcinfo << oldUrl.url() << " -> " << newUrl.url() << endl; + + KonqListViewDir *dir = m_dictSubDirs.take( oldUrl.url(-1) ); + Q_ASSERT( dir ); + m_dictSubDirs.insert( newUrl.url(-1), dir ); + // TODO: do we need to rename the fileitem in dir as well? +} + +void KonqTreeViewWidget::slotNewItems( const KFileItemList &entries ) +{ + if (!entries.count()) + return; + // Find parent item - it's the same for all the items + QPtrListIterator<KFileItem> kit( entries ); + KURL dir( (*kit)->url().upURL() ); + + KonqListViewDir *parentDir = 0L; + if ( !m_url.equals( dir, true ) ) // ignore trailing slash + parentDir = m_dictSubDirs[ dir.url(-1) ]; + + if ( !parentDir ) // hack for zeroconf://domain/type/service listed in zeroconf:/type/ dir + { + dir.setHost( QString::null ); + parentDir = m_dictSubDirs[ dir.url(-1) ]; + } + + for ( ; kit.current(); ++kit ) + { + KonqListViewDir *dirItem = 0; + KonqListViewItem *fileItem = 0; + + if ( parentDir ) // adding under a directory item + { + if ( (*kit)->isDir() ) + { + dirItem = new KonqListViewDir( this, parentDir, *kit ); + m_dictSubDirs.insert( (*kit)->url().url(-1), dirItem ); + } + else + fileItem = new KonqListViewItem( this, parentDir, *kit ); + } + else // adding on the toplevel + { + if ( (*kit)->isDir() ) + { + dirItem = new KonqListViewDir( this, *kit ); + m_dictSubDirs.insert( (*kit)->url().url(-1), dirItem ); + } + else + fileItem = new KonqListViewItem( this, *kit ); + } + + if ( !m_itemFound ) + { + if ( fileItem && fileItem->text(0) == m_itemToGoTo ) + { + setCurrentItem( fileItem ); + m_itemFound = true; + } + else if ( dirItem && dirItem->text(0) == m_itemToGoTo ) + { + setCurrentItem( dirItem ); + m_itemFound = true; + } + } + + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( fileItem ? fileItem : dirItem, true ); + } + } + + if ( fileItem && !(*kit)->isMimeTypeKnown() ) + m_pBrowserView->lstPendingMimeIconItems().append( fileItem ); + + if ( dirItem ) + { + QString u = (*kit)->url().url( 0 ); + if ( m_urlsToOpen.remove( u ) ) + dirItem->open( true, false ); + else if ( m_urlsToReload.remove( u ) ) + dirItem->open( true, true ); + } + } + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + + // counts for the statusbar + m_pBrowserView->newItems( entries ); + slotUpdateBackground(); +} + +void KonqTreeViewWidget::slotDeleteItem( KFileItem *_fileItem ) +{ + QString url = _fileItem->url().url(-1); + + // Check if this item is in m_dictSubDirs, and if yes, then remove it + slotClear( _fileItem->url() ); + + m_dictSubDirs.remove( url ); + m_urlsToOpen.remove( url ); + m_urlsToReload.remove( url ); + + KonqBaseListViewWidget::slotDeleteItem( _fileItem ); +} + +void KonqTreeViewWidget::openSubFolder( KonqListViewDir* _dir, bool _reload ) +{ + m_dirLister->openURL( _dir->item()->url(), true /* keep existing data */, _reload ); + slotUpdateBackground(); +} + +void KonqTreeViewWidget::stopListingSubFolder( KonqListViewDir* _dir ) +{ + m_dirLister->stop( _dir->item()->url() ); + slotUpdateBackground(); +} + +#include "konq_treeviewwidget.moc" diff --git a/konqueror/listview/konq_treeviewwidget.h b/konqueror/listview/konq_treeviewwidget.h new file mode 100644 index 000000000..86119a8bf --- /dev/null +++ b/konqueror/listview/konq_treeviewwidget.h @@ -0,0 +1,67 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + 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 __konq_treeviewwidget_h__ +#define __konq_treeviewwidget_h__ + +#include "konq_listviewwidget.h" +#include "konq_treeviewitem.h" +#include <qdict.h> +#include <kurl.h> +#include <klistview.h> + +class KonqListView; + + +class KonqTreeViewWidget : public KonqBaseListViewWidget +{ + friend class KonqListViewDir; + + Q_OBJECT +public: + KonqTreeViewWidget( KonqListView *parent, QWidget *parentWidget ); + virtual ~KonqTreeViewWidget(); + + virtual bool openURL( const KURL &url ); + + virtual void saveState( QDataStream &stream ); + virtual void restoreState( QDataStream &stream ); + +protected slots: + // slots connected to the directory lister + virtual void slotCompleted(); + virtual void slotCompleted( const KURL & ); + virtual void slotClear(); + virtual void slotClear( const KURL & ); + virtual void slotRedirection( const KURL &, const KURL & ); + virtual void slotNewItems( const KFileItemList & ); + virtual void slotDeleteItem( KFileItem *_fileTtem ); + +protected: + KonqListViewDir *findDir( const QString &_url ); + + void openSubFolder( KonqListViewDir *_dir, bool _reload ); + void stopListingSubFolder( KonqListViewDir *_dir ); + + // URL -> item (for directories only) + QDict<KonqListViewDir> m_dictSubDirs; + + QStringList m_urlsToOpen, m_urlsToReload; +}; + +#endif diff --git a/konqueror/pics/Makefile.am b/konqueror/pics/Makefile.am new file mode 100644 index 000000000..681ffb19c --- /dev/null +++ b/konqueror/pics/Makefile.am @@ -0,0 +1,3 @@ +KDE_ICON = AUTO + +SUBDIRS = tiles indicators actions diff --git a/konqueror/pics/actions/Makefile.am b/konqueror/pics/actions/Makefile.am new file mode 100644 index 000000000..83b19a98a --- /dev/null +++ b/konqueror/pics/actions/Makefile.am @@ -0,0 +1,3 @@ +konqiconsdir = $(kde_datadir)/konqueror/icons +konqicons_ICON = AUTO + diff --git a/konqueror/pics/actions/cr16-action-kde1.png b/konqueror/pics/actions/cr16-action-kde1.png Binary files differnew file mode 100644 index 000000000..86a3d1237 --- /dev/null +++ b/konqueror/pics/actions/cr16-action-kde1.png diff --git a/konqueror/pics/actions/cr16-action-kde2.png b/konqueror/pics/actions/cr16-action-kde2.png Binary files differnew file mode 100644 index 000000000..15bf0ae76 --- /dev/null +++ b/konqueror/pics/actions/cr16-action-kde2.png diff --git a/konqueror/pics/actions/cr16-action-kde3.png b/konqueror/pics/actions/cr16-action-kde3.png Binary files differnew file mode 100644 index 000000000..86a3d1237 --- /dev/null +++ b/konqueror/pics/actions/cr16-action-kde3.png diff --git a/konqueror/pics/actions/cr16-action-kde4.png b/konqueror/pics/actions/cr16-action-kde4.png Binary files differnew file mode 100644 index 000000000..15bf0ae76 --- /dev/null +++ b/konqueror/pics/actions/cr16-action-kde4.png diff --git a/konqueror/pics/actions/cr16-action-kde5.png b/konqueror/pics/actions/cr16-action-kde5.png Binary files differnew file mode 100644 index 000000000..86a3d1237 --- /dev/null +++ b/konqueror/pics/actions/cr16-action-kde5.png diff --git a/konqueror/pics/actions/cr16-action-kde6.png b/konqueror/pics/actions/cr16-action-kde6.png Binary files differnew file mode 100644 index 000000000..15bf0ae76 --- /dev/null +++ b/konqueror/pics/actions/cr16-action-kde6.png diff --git a/konqueror/pics/hi128-app-konqueror.png b/konqueror/pics/hi128-app-konqueror.png Binary files differnew file mode 100644 index 000000000..c032a6e06 --- /dev/null +++ b/konqueror/pics/hi128-app-konqueror.png diff --git a/konqueror/pics/hi16-app-kfm.png b/konqueror/pics/hi16-app-kfm.png Binary files differnew file mode 100644 index 000000000..4969259fc --- /dev/null +++ b/konqueror/pics/hi16-app-kfm.png diff --git a/konqueror/pics/hi16-app-konqueror.png b/konqueror/pics/hi16-app-konqueror.png Binary files differnew file mode 100644 index 000000000..013f78bc4 --- /dev/null +++ b/konqueror/pics/hi16-app-konqueror.png diff --git a/konqueror/pics/hi22-app-kfm.png b/konqueror/pics/hi22-app-kfm.png Binary files differnew file mode 100644 index 000000000..ea35e364c --- /dev/null +++ b/konqueror/pics/hi22-app-kfm.png diff --git a/konqueror/pics/hi22-app-konqueror.png b/konqueror/pics/hi22-app-konqueror.png Binary files differnew file mode 100644 index 000000000..1413af913 --- /dev/null +++ b/konqueror/pics/hi22-app-konqueror.png diff --git a/konqueror/pics/hi32-app-kfm.png b/konqueror/pics/hi32-app-kfm.png Binary files differnew file mode 100644 index 000000000..699c0ddd4 --- /dev/null +++ b/konqueror/pics/hi32-app-kfm.png diff --git a/konqueror/pics/hi32-app-konqueror.png b/konqueror/pics/hi32-app-konqueror.png Binary files differnew file mode 100644 index 000000000..ed21ceb5e --- /dev/null +++ b/konqueror/pics/hi32-app-konqueror.png diff --git a/konqueror/pics/hi48-app-kfm.png b/konqueror/pics/hi48-app-kfm.png Binary files differnew file mode 100644 index 000000000..bb0b2a7f8 --- /dev/null +++ b/konqueror/pics/hi48-app-kfm.png diff --git a/konqueror/pics/hi48-app-konqueror.png b/konqueror/pics/hi48-app-konqueror.png Binary files differnew file mode 100644 index 000000000..11d84db32 --- /dev/null +++ b/konqueror/pics/hi48-app-konqueror.png diff --git a/konqueror/pics/hi64-app-kfm.png b/konqueror/pics/hi64-app-kfm.png Binary files differnew file mode 100644 index 000000000..4d2b58bcc --- /dev/null +++ b/konqueror/pics/hi64-app-kfm.png diff --git a/konqueror/pics/hi64-app-konqueror.png b/konqueror/pics/hi64-app-konqueror.png Binary files differnew file mode 100644 index 000000000..637751f61 --- /dev/null +++ b/konqueror/pics/hi64-app-konqueror.png diff --git a/konqueror/pics/hisc-app-konqueror.svgz b/konqueror/pics/hisc-app-konqueror.svgz Binary files differnew file mode 100644 index 000000000..a5c101de5 --- /dev/null +++ b/konqueror/pics/hisc-app-konqueror.svgz diff --git a/konqueror/pics/indicators/Makefile.am b/konqueror/pics/indicators/Makefile.am new file mode 100644 index 000000000..06d55e999 --- /dev/null +++ b/konqueror/pics/indicators/Makefile.am @@ -0,0 +1,4 @@ +picsdir = $(kde_datadir)/konqueror/pics +pics_DATA = indicator_connect.png \ + indicator_noconnect.png indicator_empty.png indicator_viewactive.png + diff --git a/konqueror/pics/indicators/indicator_connect.png b/konqueror/pics/indicators/indicator_connect.png Binary files differnew file mode 100644 index 000000000..feff45c6a --- /dev/null +++ b/konqueror/pics/indicators/indicator_connect.png diff --git a/konqueror/pics/indicators/indicator_empty.png b/konqueror/pics/indicators/indicator_empty.png Binary files differnew file mode 100644 index 000000000..dcb847550 --- /dev/null +++ b/konqueror/pics/indicators/indicator_empty.png diff --git a/konqueror/pics/indicators/indicator_noconnect.png b/konqueror/pics/indicators/indicator_noconnect.png Binary files differnew file mode 100644 index 000000000..5f14df0a0 --- /dev/null +++ b/konqueror/pics/indicators/indicator_noconnect.png diff --git a/konqueror/pics/indicators/indicator_viewactive.png b/konqueror/pics/indicators/indicator_viewactive.png Binary files differnew file mode 100644 index 000000000..f8af065d8 --- /dev/null +++ b/konqueror/pics/indicators/indicator_viewactive.png diff --git a/konqueror/pics/tiles/Makefile.am b/konqueror/pics/tiles/Makefile.am new file mode 100644 index 000000000..013770f95 --- /dev/null +++ b/konqueror/pics/tiles/Makefile.am @@ -0,0 +1,3 @@ +tilesdir = $(kde_datadir)/konqueror/tiles +tiles_DATA = bluemorning.png canvas.png kde4ever.png \ + kenwimer.png noise.png paper_flieder.png redfiber.png diff --git a/konqueror/pics/tiles/bluemorning.png b/konqueror/pics/tiles/bluemorning.png Binary files differnew file mode 100644 index 000000000..4dd027f33 --- /dev/null +++ b/konqueror/pics/tiles/bluemorning.png diff --git a/konqueror/pics/tiles/canvas.png b/konqueror/pics/tiles/canvas.png Binary files differnew file mode 100644 index 000000000..9dd8010a0 --- /dev/null +++ b/konqueror/pics/tiles/canvas.png diff --git a/konqueror/pics/tiles/kde4ever.png b/konqueror/pics/tiles/kde4ever.png Binary files differnew file mode 100644 index 000000000..0ff7b8e9a --- /dev/null +++ b/konqueror/pics/tiles/kde4ever.png diff --git a/konqueror/pics/tiles/kenwimer.png b/konqueror/pics/tiles/kenwimer.png Binary files differnew file mode 100644 index 000000000..7642a294e --- /dev/null +++ b/konqueror/pics/tiles/kenwimer.png diff --git a/konqueror/pics/tiles/noise.png b/konqueror/pics/tiles/noise.png Binary files differnew file mode 100644 index 000000000..c39730093 --- /dev/null +++ b/konqueror/pics/tiles/noise.png diff --git a/konqueror/pics/tiles/paper_flieder.png b/konqueror/pics/tiles/paper_flieder.png Binary files differnew file mode 100644 index 000000000..a1a014bab --- /dev/null +++ b/konqueror/pics/tiles/paper_flieder.png diff --git a/konqueror/pics/tiles/redfiber.png b/konqueror/pics/tiles/redfiber.png Binary files differnew file mode 100644 index 000000000..3618ca783 --- /dev/null +++ b/konqueror/pics/tiles/redfiber.png diff --git a/konqueror/preloader/Makefile.am b/konqueror/preloader/Makefile.am new file mode 100644 index 000000000..8ecaba5ad --- /dev/null +++ b/konqueror/preloader/Makefile.am @@ -0,0 +1,21 @@ +AM_CPPFLAGS = -DQT_NO_CAST_ASCII + +kde_module_LTLIBRARIES = kded_konqy_preloader.la + +INCLUDES= -I.. $(all_includes) +kded_konqy_preloader_la_SOURCES = preloader.cc preloader.skel +kded_konqy_preloader_la_LDFLAGS = $(all_libraries) -module -avoid-version +kded_konqy_preloader_la_LIBADD = ../libkonqueror_intern.la $(LIB_KSYCOCA) $(LIB_KDECORE) + +METASOURCES = AUTO + +KonquerorIface_DIR = $(srcdir)/.. + +servicesdir = $(kde_servicesdir)/kded +services_DATA = konqy_preloader.desktop + +autostartdir = $(datadir)/autostart +autostart_DATA = konqy_preload.desktop + +####### Build rules +preloader.lo: ../konq_settingsxt.h diff --git a/konqueror/preloader/configure.in.in b/konqueror/preloader/configure.in.in new file mode 100644 index 000000000..315b23c97 --- /dev/null +++ b/konqueror/preloader/configure.in.in @@ -0,0 +1,151 @@ +dnl check whether mallinfo() is available and which fields to use to find out memory usage +dnl it's used in konq_mainwindow.cc +dnl warning, ugly code ahead +dnl some implementations have mallinfo() in stdlib.h, others in malloc.h +dnl fields showing memory usage should be hblkhd, uordblks and usmblks, +dnl different implementations use different combinations of these (which is ok), +dnl but some of them "reuse" fields they don't use for other purposes + +AC_DEFUN([KDE_MALLINFO_CHECK], +[ +AC_MSG_CHECKING([for mallinfo() in $1]) +AC_CACHE_VAL(kde_cv_func_mallinfo_$2, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([#include $1], + [ + struct mallinfo m; + int dummy; + m = mallinfo(); + dummy = m.hblkhd; + dummy = m.uordblks; + dummy = m.usmblks; + dummy = dummy; + ], + kde_cv_func_mallinfo_$2=yes, + kde_cv_func_mallinfo_$2=no) + AC_LANG_RESTORE + ]) +if test "$kde_cv_func_mallinfo_$2" = "yes"; then + kde_mallinfo_type=$2 +fi +AC_MSG_RESULT($kde_cv_func_mallinfo_$2) +]) + + +AC_DEFUN([KDE_MALLINFO_CHECK_FIELD], +[ +AC_MSG_CHECKING([whether to use mallinfo field $1]) +AC_CACHE_VAL(kde_cv_func_mallinfo_field_$1, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_RUN( + [ + +#include <$kde_mallinfo_type.h> +enum use_type { No, Yes, Never }; +use_type use_field = No; +const int SIZE = 4 * 1024 * 1024; +const int SMALL_SIZE = 4 * 1024; + +void dif( struct mallinfo& m1, struct mallinfo& m2, bool alloc ) + { + int difval = m2.$1 - m1.$1; + if( alloc ) + { + if( difval >= SIZE && difval < 2 * SIZE && use_field != Never ) + use_field = Yes; + } + else // !alloc + { + difval = -difval; + if( difval > SMALL_SIZE && ( difval < SIZE || difval >= 2 * SIZE ) && use_field == Yes ) + use_field = Never; + } + } + +int main() + { + free( malloc( SIZE * 2 )); // avoid Doug Lea's malloc feature of having total_max in usmblks + struct mallinfo m1 = mallinfo(); + void* mem1 = malloc( SIZE ); + struct mallinfo m2 = mallinfo(); + free( mem1 ); + struct mallinfo m3 = mallinfo(); + void* mem2[ SIZE / 32 ]; + for( int i = 0; + i < SIZE / 32; + ++i ) + mem2[ i ] = malloc( 32 ); + struct mallinfo m4 = mallinfo(); + for( int i = 0; + i < SIZE / 32; + ++i ) + free( mem2[ i ] ); + struct mallinfo m5 = mallinfo(); + void* mem3[ SIZE / 1024 ]; + for( int i = 0; + i < SIZE / 1024; + ++i ) + mem3[ i ] = malloc( 1024 ); + struct mallinfo m6 = mallinfo(); + for( int i = 0; + i < SIZE / 1024; + ++i ) + free( mem3[ i ] ); + struct mallinfo m7 = mallinfo(); + dif( m1, m2, true ); + dif( m2, m3, false ); + dif( m3, m4, true ); + dif( m4, m5, false ); + dif( m5, m6, true ); + dif( m6, m7, false ); + return use_field == Yes ? 0 : 1; + } + + ], + [kde_cv_func_mallinfo_field_$1=yes], + [kde_cv_func_mallinfo_field_$1=no], + [kde_cv_func_mallinfo_field_$1=no]) + AC_LANG_RESTORE + ]) +AC_MSG_RESULT($kde_cv_func_mallinfo_field_$1) +kde_mallinfo_$1=$kde_cv_func_mallinfo_field_$1 +if test "$kde_mallinfo_$1" = "yes"; then + AC_DEFINE( KDE_MALLINFO_FIELD_$1, 1, [Use mallinfo field $1]) +fi +]) + + +kde_mallinfo_type= +KDE_MALLINFO_CHECK([<stdlib.h>],stdlib) +if test -z "$kde_mallinfo_type"; then + KDE_MALLINFO_CHECK([<malloc.h>],malloc) +fi + +AC_TRY_LINK_FUNC(mallinfo, + [], + [ AC_CHECK_LIB(malloc,mallinfo, + [ AC_SUBST(LIBMALLOC,"-lmalloc") ], + [ kde_mallinfo_type="" ]) + ]) + +if test -n "$kde_mallinfo_type"; then + KDE_MALLINFO_CHECK_FIELD(hblkhd) + KDE_MALLINFO_CHECK_FIELD(uordblks) + KDE_MALLINFO_CHECK_FIELD(usmblks) + if test -z "$kde_mallinfo_hblkhd" -a \ + -z "$kde_mallinfo_uordblks" -a \ + -z "$kde_mallinfo_usmblks"; then + kde_mallinfo_type= + fi +fi + + +if test "$kde_mallinfo_type" = "stdlib"; then + AC_DEFINE(KDE_MALLINFO_STDLIB, 1, [mallinfo() is available in <stdlib.h>]) +elif test "$kde_mallinfo_type" = "malloc"; then + AC_DEFINE(KDE_MALLINFO_MALLOC, 1, [mallinfo() is available in <malloc.h>]) +fi diff --git a/konqueror/preloader/konqy_preload.desktop b/konqueror/preloader/konqy_preload.desktop new file mode 100644 index 000000000..48061a669 --- /dev/null +++ b/konqueror/preloader/konqy_preload.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Exec=konqueror --preload +Type=Application +Name=Konqueror Preloading During KDE startup +Name[af]=Vroegtydige laai van Konqueror tydens KDE opstart +Name[ar]=تحميل Konqueror التمهيدي خلال بدء تشغيل KDE +Name[az]=KDE Başlanğıcında Konqueror-un Ön Yüklənməsi +Name[be]=Папярэдняя загрузка Konqueror падчас запуску KDE +Name[bg]=Зареждане на браузъра при стартиране +Name[bn]=কে.ডি.ই. আরম্ভকালীন কনকরার প্রিলোড +Name[bs]=Konqueror pre-učitavanje tokom pokretanja KDEa +Name[ca]=Precàrrega del Konqueror durant l'engegada del KDE +Name[cs]=Načtení Konqueroru dopředu během spuštění KDE +Name[csb]=Wstãpny wladënk Konquerora przë zrëszaniu KDE +Name[cy]=Cynlwytho Konqueror yn ystod Ymgychwyn KDE +Name[da]=Konqueror forhåndsindlæsning ved opstart +Name[de]=Konqueror bei KDE-Start im Hintergrund laden +Name[el]=Προφόρτωση του Konqueror κατά την εκκίνηση του KDE +Name[eo]=Konkeranto antaŭŝarĝante dum KDE-lanĉo +Name[es]=Precargado de Konqueror durante el arranque de KDE +Name[et]=Konquerori eellaadimine KDE käivitamisel +Name[eu]=Konquerorren aurrekarga KDE abiatzen den bitartean +Name[fa]=پیشبارگذاری Konqueror در طول راهاندازی KDE +Name[fi]=Konquerorin esilataus KDE:n käynnistyksessä +Name[fr]=Préchargement de Konqueror lors du démarrage de KDE +Name[fy]=Konqueror foarlade ûnder it begjinnen fan KDE +Name[ga]=Réamhluchtú Konqueror ag am tosaithe KDE +Name[gl]=Precarga de Konqueror durante o início de KDE +Name[he]=טעינה מוקדמת של Konqueror בזמן עלית KDE +Name[hi]=केडीई चालू होने के दौरान कॉन्करर प्रीलोड हो रहा है +Name[hr]=Konqueror pred-učitavanje tijekom podizanja KDE-a +Name[hu]=Konqueror-gyorsbetöltő +Name[is]=Konqueror ræsir þegar KDE ræsir +Name[it]=Precaricamento di Konqueror durante l'avvio di KDE +Name[ja]=KDE 起動時に Konqueror をプリロードします +Name[ka]=Konqueror-ის წინჩატვირთვა KDE-ს გაშვებისას +Name[kk]=KDE бастағанда Konqueror-ді алдын-ала жүктеу +Name[km]=ប្រុងប្រៀបផ្ទុក Konqueror កំឡុងពេលចាប់ផ្ដើម KDE +Name[ko]=KDE 시작 중 Konqueror 미리 불러오기 +Name[lt]=Įkelti Konqueror paleidžiant KDE +Name[lv]=Iekarotāja priekšielāde KDE palaišanās laikā +Name[mk]=Konqueror се предвчитува за време на подигањето на KDE +Name[ms]=Prapemuatan Konqueror Semasa pemulaan KDE +Name[mt]=Tlugħ ta' Konqueror waqt li jitla' KDE +Name[nb]=Forhåndslast Konqueror når KDE starter +Name[nds]=Konqueror vörladen bi't Hoochfohren vun KDE +Name[ne]=KDE सुरुआत गर्दा पहिले लोड गरिएको कन्क्वेरर +Name[nl]=Konqueror voorladen tijdens KDE-start +Name[nn]=Førehandslast Konqueror når KDE startar +Name[pa]=ਕੋਨਕਿਉਰੋਰ ਪਹਿਲਾਂ ਹੀ KDE ਦੀ ਸ਼ੁਰੂਆਤ 'ਤੇ ਹੀ ਲੋਡ ਹੋ ਜਾਦਾ ਹੈ +Name[pl]=Wstępne wczytanie Konquerora przy uruchamianiu KDE +Name[pt]=Pré-Carregamento do Konqueror no Arranque do KDE +Name[pt_BR]=Pré-carregamento do Konqueror no início do KDE +Name[ro]=Preîncărcare Konqueror la pornirea KDE +Name[ru]=Предварительная загрузка Konqueror при запуске KDE +Name[rw]=Ugutangirambere kwa Konqueror mu gihe cy'itangira rya KDE +Name[se]=Viečča Konquerora ovdagihtii go KDE vuolgá johtui +Name[sk]=Prednahratie Konquerora počas štartu KDE +Name[sl]=Prednalaganje Konquerorja med zaganjanjem KDE +Name[sr]=Предучитавање Konqueror-а приликом покретања KDE-а +Name[sr@Latn]=Predučitavanje Konqueror-a prilikom pokretanja KDE-a +Name[sv]=Förladdning av Konqueror vid start av KDE +Name[ta]=கேடியி துவக்கத்தின்போது கான்கொரரை முன் ஏற்றுதல் +Name[th]=ให้โหลดคอนเควอร์เรอร์ล่วงหน้า ขณะ KDE เริ่มทำงานริ่มทำงาน +Name[tr]=KDE açılışında Konqueror Önyüklemesi +Name[tt]=Konqueror'nı Aldan uq Yökläw +Name[uk]=Попереднє завантаження Konqueror при старті KDE +Name[vi]=Tải sẵn Konqueror Trong lúc Khởi động KDE +Name[wa]=Prétcherdjî Konqueror tins l' enondaedje di KDE +Name[zh_CN]=在 KDE 启动时预先装入 Konqueror +Name[zh_TW]=啟動 KDE 時預先載入 Konqueror +X-KDE-autostart-condition=konquerorrc:Reusing:PreloadOnStartup:false +X-KDE-StartupNotify=false +X-KDE-autostart-phase=2 +OnlyShowIn=KDE; diff --git a/konqueror/preloader/konqy_preloader.desktop b/konqueror/preloader/konqy_preloader.desktop new file mode 100644 index 000000000..da06b467a --- /dev/null +++ b/konqueror/preloader/konqy_preloader.desktop @@ -0,0 +1,146 @@ +[Desktop Entry] +Type=Service +Name=KDED Konqueror Preloader Module +Name[af]=KDED Konqueror Vroegtydige Laai Module +Name[ar]=وحدة تمهيد التحميل لِــ KDED Konqueror +Name[az]=KDED Konqueror Ön Yüklənmə Modulu +Name[be]=Модуль папярэдняй загрузкі Konqueror KDED +Name[bn]=KDED কনকরার প্রি-লোডার মডিউল +Name[bs]=KDED modul za pre-učitavanje Konquerora +Name[ca]=Mòdul de precàrrega del Konqueror KDED +Name[cs]=KDED modul pro načítání Konqueroru +Name[csb]=Mòduł wstãpnegò wladënkù Konquerora +Name[cy]=Modiwl Cynlwytho Konqueror KDED +Name[da]=KDED Konqueror forindlæsningsmodul +Name[de]=Konqueror-Schnellstart +Name[el]=KDED άρθρωμα Προφόρτωσης του Konqueror +Name[eo]=KDED-Konkeranta antaŭŝarĝomodulo +Name[es]=Módulo de precarga de Konqueror KDED +Name[et]=KDED Konquerori eellaadimise moodul +Name[eu]=KDED Konqueror aurrekargatze modulua +Name[fa]=پیمانۀ پیشبارکنندۀ KDED Konqueror +Name[fi]=Konquerorin esilatausmoduuli KDED:lle +Name[fr]=Module KDED de préchargement de Konqueror +Name[fy]=KDED Konqueror Foarlaad-module +Name[ga]=Modúl Réamhluchtú Konqueror KDED +Name[gl]=Módulo KDED de Precarga de Konqueror +Name[he]=מודול KDED Konqueror Preloader +Name[hi]=केडीईडी कॉन्क्वेरर प्रीलोडर मॉड्यूल +Name[hr]=KDED Konqueror modul pred-učitavanja +Name[hu]=KDED gyorsbetöltő modul a Konquerorhoz +Name[is]=KDED Konqueror forræsingareining +Name[it]=Modulo di KDED per precaricare Konqueror +Name[ja]=KDED Konqueror プリロードモジュール +Name[ka]=Konqueror-ის წინჩატვირთვის მოდული KDED +Name[kk]=KDED деген Konqueror-ді алдын-ала жүктеу модулі +Name[km]=ម៉ូឌុលកម្មវិធីប្រុងប្រៀបផ្ទុក KDED Konqueror +Name[ko]=KDED Konqueror 프리로더 모듈 +Name[lt]=KDED Konqueror išankstinio įkrovimo modulis +Name[lv]=KDED Iekarotāja priekšielādēšanas modulis +Name[mk]=Модул на KDED за предвчитување на Konqueror +Name[ms]=Modul Pramuat Konqueror KDE +Name[mt]=Modulu biex itella' Konqueror fil-bidu +Name[nb]=KDED-modul for å forhåndslaste Konqueror +Name[nds]=KDED-Moduul för't Vörladen vun Konqueror +Name[ne]=KDED कन्क्वेरर प्रीलोडर मेनु +Name[nl]=KDED Konqueror Preloader-module +Name[nn]=KDED-modul for førehandslasting av Konqueror +Name[pa]=KDED ਕੋਨਕਿਉਰੋਰ ਪਹਿਲਾਂ ਲੋਡ ਮੇਡੀਊਲ +Name[pl]=Moduł KDED wstępnego wczytania Konquerora +Name[pt]=Módulo KDED de Pré-Carregamento do Konqueror +Name[pt_BR]=Módulo de Pré-carregamento do Konqueror +Name[ro]=Modul KDED de preîncărcare Konqueror +Name[ru]=Предварительная загрузка Konqueror +Name[rw]=Igice Mutangizambere KDE Konqueror +Name[sk]=Modul KDED prednahrania Konquerora +Name[sl]=Modul KDED za prednalaganje Konquerorja +Name[sr]=Модул за предучитавање Konqueror-а, KDED +Name[sr@Latn]=Modul za predučitavanje Konqueror-a, KDED +Name[sv]=KDED Konqueror-förladdningsmodul +Name[ta]=KDED கான்கொரர் முன் ஏற்றக்கூடிய பகுதி +Name[th]=โมดูลโหลดคอนเควอร์เรอร์ล่วงหน้าของ KDED +Name[tr]=KDED Konqueror Önyükleme Modülü +Name[tt]=Konqueror'nı Aldan uq Yökläw +Name[uk]=Модуль KDED для попереднього завантаження Konqueror +Name[vi]=Mô đun Tải sẵn Konqueror KDED +Name[wa]=Module KDED di prétcherdjaedje di Konqueror +Name[zh_CN]=KDED Konqueror 预装入模块 +Name[zh_TW]=KDED Konqueror 預先載入模組 +Comment=Reduces Konqueror startup time +Comment[af]=Verminder Konqueror se opstart tyd +Comment[ar]=Konqueror يقلّل من وقت بدء تشغيل +Comment[az]=Konqueror-un başlanğıc sürəsini azaldır +Comment[be]=Змяншае час запуску Konqueror +Comment[bg]=Намаляване на времето за стартиране на браузъра +Comment[bn]=কনকরার চালু করার সময় কমায় +Comment[bs]=Skraćuje vrijeme za pokretanje Konquerora +Comment[ca]=Redueix el temps d'inici del Konqueror +Comment[cs]=Redukuje čas pro spuštění Konqueroru +Comment[csb]=Zmiészô czas zrëszaniô Konquerora +Comment[cy]=Lleihau amser ymgychwyn Konqueror +Comment[da]=Reducerer Konquerors opstartstid +Comment[de]=Lädt Konqueror im Voraus und verringert so die Ladezeit +Comment[el]=Μειώνει το χρόνο εκκίνησης του Konqueror +Comment[eo]=Mallongigas la Konkerantan starttempon +Comment[es]=Reduce el tiempo de inicio de Konqueror +Comment[et]=Kahandab Konquerori käivitamise aega +Comment[eu]=Konquerorren abiatze denbora laburtzen du +Comment[fa]=زمان راهاندازی Konqueror را کاهش میدهد +Comment[fi]=Vähentää Konquerorin käynnistysaikaa +Comment[fr]=Réduit le temps de démarrage de Konqueror +Comment[fy]=Redusearret de begjintiid fan Konqueror +Comment[ga]=Laghdaíonn sé seo an t-am chun Konqueror a thosú +Comment[gl]=Reduce o tempo de início de Konqueror +Comment[he]=מוריד את זמן הפעלת Konqueror +Comment[hi]=कॉन्करर के चालू होने के समय को कम करता है +Comment[hr]=Ubrzava pokretanje Konquerora +Comment[hu]=A Konqueror elindulási idejének lecsökkentése +Comment[is]=Dregur úr ræsingatíma Konqueror vafrans +Comment[it]=Riduce il tempo di avvio di Konqueror +Comment[ja]=Konqueror の起動時間を短縮します +Comment[ka]=ამცირებს Konqueror-ის გაშვების დროს +Comment[kk]=Konqueror-ді жүктеу уақытын қысқартады +Comment[km]=បន្ថយរយៈពេលចាប់ផ្ដើមរបស់ Konqueror +Comment[ko]=Konqueror 시작 시간을 줄입니다 +Comment[lt]=Sutrumpina Konqueror paleidimo laiką +Comment[lv]=Samazina Iekarotāja palaišanas laiku +Comment[mk]=Го намалува времето за стартување на Konqueror +Comment[mn]=Конкюрорын эхлэх хугацааг багасгах +Comment[ms]=Mengurangkan masa pemulaan Konqueror +Comment[mt]=Inaqqas id-dewmien biex jitla' Konqueror +Comment[nb]=Reduserer oppstartstida for Konqueror +Comment[nds]=Bringt de Starttiet vun Konqueror daal +Comment[ne]=कन्क्वेरर सुरुआत समय घटाउँछ +Comment[nl]=Reduceert de opstarttijd van Konqueror +Comment[nn]=Reduserer oppstartstida til Konqueror +Comment[pa]=ਇਹ ਕੋਨਕਿਉਰੋਰ ਦਾ ਸ਼ੁਰੂਆਤੀ ਸਮਾਂ ਘਟਾਉਦਾ ਹੈ +Comment[pl]=Zmniejsza czas uruchomienia Konquerora +Comment[pt]=Reduz o tempo de arranque do Konqueror +Comment[pt_BR]=Reduz o tempo de inicialização do Konqueror +Comment[ro]=Reduce timpul de pornire al Konqueror +Comment[ru]=Предварительная загрузка Konqueror во время запуска KDE +Comment[rw]=Igabanya igihe cy'itangira cya Konqueror +Comment[se]=Unnida Konquerora álggahanáiggi +Comment[sk]=Zmenšuje dobu štartu Konquerora +Comment[sl]=Skrajša zagonski čas Konquerorja +Comment[sr]=Смањује време потребно за покретање Konqueror-а +Comment[sr@Latn]=Smanjuje vreme potrebno za pokretanje Konqueror-a +Comment[sv]=Minskar Konquerors starttid +Comment[ta]=கான்கொரர் துவக்க நேரத்தை குறைக்கிறது +Comment[te]=కాంకెరర్ మొదలు సమయాన్ని తగ్గించును +Comment[th]=ลดเวลาที่ใช้เริ่มทำงานของคอนเควอร์เรอร์ +Comment[tr]=Konqueror açılış zamanını azaltır +Comment[tt]=Konqueror cibärüen tizlätä +Comment[uk]=Зменшує час запуску Konqueror +Comment[uz]=Konqueror ishga tushish vaqtini kamaytirish +Comment[uz@cyrillic]=Konqueror ишга тушиш вақтини камайтириш +Comment[vi]=Giảm thời gian khởi động Konqueror +Comment[wa]=Fwait enonder pus raddimint Konqueror +Comment[zh_CN]=减少 Konqueror 启动时间 +Comment[zh_TW]=減少 Konqueror 啟動時間 +ServiceTypes=KDEDModule +X-KDE-ModuleType=Library +X-KDE-Library=konqy_preloader +X-KDE-FactoryName=konqy_preloader +X-KDE-Kded-autoload=false +X-KDE-Kded-load-on-demand=true diff --git a/konqueror/preloader/preloader.cc b/konqueror/preloader/preloader.cc new file mode 100644 index 000000000..a60604e86 --- /dev/null +++ b/konqueror/preloader/preloader.cc @@ -0,0 +1,151 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Lubos Lunak <[email protected]> + + 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 "preloader.h" +#include "konq_settingsxt.h" + +#include <kconfig.h> +#include <dcopref.h> +#include <kapplication.h> +#include <dcopclient.h> +#include <kdebug.h> + +KonqyPreloader::KonqyPreloader( const QCString& obj ) + : KDEDModule( obj ) + { + reconfigure(); + connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString& )), + SLOT( appRemoved( const QCString& ))); + connect( &check_always_preloaded_timer, SIGNAL( timeout()), + SLOT( checkAlwaysPreloaded())); + } + +KonqyPreloader::~KonqyPreloader() + { + updateCount(); + } + +bool KonqyPreloader::registerPreloadedKonqy( QCString id, int screen ) + { + if( instances.count() >= (uint)KonqSettings::maxPreloadCount() ) + return false; + instances.append( KonqyData( id, screen )); + return true; + } + +QCString KonqyPreloader::getPreloadedKonqy( int screen ) + { + if( instances.count() == 0 ) + return ""; + for( InstancesList::Iterator it = instances.begin(); + it != instances.end(); + ++it ) + { + if( (*it).screen == screen ) + { + QCString ret = (*it).id; + instances.remove( it ); + check_always_preloaded_timer.start( 5000, true ); + return ret; + } + } + return ""; + } + +void KonqyPreloader::unregisterPreloadedKonqy( QCString id_P ) + { + for( InstancesList::Iterator it = instances.begin(); + it != instances.end(); + ++it ) + if( (*it).id == id_P ) + { + instances.remove( it ); + return; + } + } + +void KonqyPreloader::appRemoved( const QCString& id ) + { + unregisterPreloadedKonqy( id ); + } + +void KonqyPreloader::reconfigure() + { + KonqSettings::self()->readConfig(); + updateCount(); + // Ignore "PreloadOnStartup" here, it's used by the .desktop file + // in the autostart folder, which will do 'konqueror --preload' in autostart + // phase 2. This will also cause activation of this kded module. + } + +void KonqyPreloader::updateCount() + { + while( instances.count() > (uint)KonqSettings::maxPreloadCount() ) + { + KonqyData konqy = instances.first(); + instances.pop_front(); + DCOPRef ref( konqy.id, "KonquerorIface" ); + ref.send( "terminatePreloaded" ); + } + if( KonqSettings::alwaysHavePreloaded() && + KonqSettings::maxPreloadCount() > 0 && + instances.count() == 0 ) + { + if( !check_always_preloaded_timer.isActive()) + { + if( kapp->kdeinitExec( QString::fromLatin1( "konqueror" ), + QStringList() << QString::fromLatin1( "--preload" ), NULL, NULL, "0" ) == 0 ) + { + kdDebug( 1202 ) << "Preloading Konqueror instance" << endl; + check_always_preloaded_timer.start( 5000, true ); + } + // else do nothing, the launching failed + } + } + } + +// have 5s interval between attempts to preload a new konqy +// in order not to start many of them at the same time +void KonqyPreloader::checkAlwaysPreloaded() + { + // TODO here should be detection whether the system is too busy, + // and delaying preloading another konqy in such case + // but I have no idea how to do it + updateCount(); + } + +void KonqyPreloader::unloadAllPreloaded() + { + while( instances.count() > 0 ) + { + KonqyData konqy = instances.first(); + instances.pop_front(); + DCOPRef ref( konqy.id, "KonquerorIface" ); + ref.send( "terminatePreloaded" ); + } + // ignore 'always_have_preloaded' here + } + +extern "C" +KDE_EXPORT KDEDModule *create_konqy_preloader( const QCString& obj ) + { + return new KonqyPreloader( obj ); + } + +#include "preloader.moc" diff --git a/konqueror/preloader/preloader.h b/konqueror/preloader/preloader.h new file mode 100644 index 000000000..2a667e462 --- /dev/null +++ b/konqueror/preloader/preloader.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Lubos Lunak <[email protected]> + + 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 _KONQUEROR_PRELOADER_H +#define _KONQUEROR_PRELOADER_H + +#include <kdedmodule.h> +#include <qtimer.h> + +class KonqyPreloader + : public KDEDModule + { + Q_OBJECT + K_DCOP + public: + KonqyPreloader( const QCString& obj ); + virtual ~KonqyPreloader(); + k_dcop: + bool registerPreloadedKonqy( QCString id, int screen ); + QCString getPreloadedKonqy( int screen ); + ASYNC unregisterPreloadedKonqy( QCString id ); + void reconfigure(); + void unloadAllPreloaded(); + private slots: + void appRemoved( const QCString& id ); + void checkAlwaysPreloaded(); + private: + void updateCount(); + struct KonqyData + { + KonqyData() {}; // for QValueList + KonqyData( const QCString& id_P, int screen_P ) + : id( id_P ), screen( screen_P ) {} + QCString id; + int screen; + }; + typedef QValueList< KonqyData > InstancesList; + InstancesList instances; + QTimer check_always_preloaded_timer; + }; + +#endif diff --git a/konqueror/profile_filemanagement.desktop b/konqueror/profile_filemanagement.desktop new file mode 100644 index 000000000..8f4452387 --- /dev/null +++ b/konqueror/profile_filemanagement.desktop @@ -0,0 +1,95 @@ +[Profile] +Container0_Children=View1,View2 +Container0_Orientation=Horizontal +Container0_SplitterSizes=30,100 +Name=File Management +Name[af]=Lêer Bestuurder +Name[ar]=تدبير الملفات +Name[az]=Fayl İdarəcisi +Name[be]=Кіраванне файламі +Name[bn]=ফাইল ব্যবস্থাপনা +Name[br]=Mererezh ar restroù +Name[bs]=Upravljanje datotekama +Name[ca]=Gestió de fitxers +Name[cs]=Správa souborů +Name[csb]=Sprôwianié lopkama +Name[cy]=Trefnu Ffeiliau +Name[da]=Filhåndtering +Name[de]=Dateiverwaltung +Name[el]=Διαχείριση αρχείων +Name[eo]=Dosieradministrilo +Name[es]=Administración de archivos +Name[et]=Failihaldur +Name[eu]=Fitxategi kudeaketa +Name[fa]=مدیریت پرونده +Name[fi]=Tiedostonhallinta +Name[fr]=Gestion de fichiers +Name[fy]=Triembehear +Name[ga]=Bainistiú Comhaid +Name[gl]=Xestión de Ficheiros +Name[he]=ניהול קבצים +Name[hi]=फ़ाइल प्रबंधन +Name[hr]=Upravitelj datotekama +Name[hu]=Fájlkezelő +Name[id]=Manajemen File +Name[is]=Skráastjóri +Name[it]=Gestione file +Name[ja]=ファイルマネージメント +Name[ka]=ფაილთა მართვა +Name[kk]=Файдарды басқару +Name[km]=ការគ្រប់គ្រងឯកសារ +Name[ko]=파일 관리자 +Name[lo]=ການຈັດການແຟ້ມ +Name[lt]=Bylų valdymas +Name[lv]=Failu Menedžments +Name[mk]=Менаџмент на датотеки +Name[mn]=Файлын удирдлага +Name[ms]=Pengurusan Fail +Name[mt]=Maniġġjar tal-Fajls +Name[nb]=Filbehandling +Name[nds]=Dateipleeg +Name[ne]=फाइल व्यवस्थापन +Name[nl]=Bestandsbeheer +Name[nn]=Filhandsaming +Name[nso]=Taolo ya Faele +Name[oc]=Gestion de fiquièrs +Name[pa]=ਫਾਇਲ ਪਰਬੰਧਨ +Name[pl]=Zarządzanie plikami +Name[pt]=Gestão de Ficheiros +Name[pt_BR]=Gerenciamento de arquivos +Name[ro]=Administrare fișiere +Name[ru]=Управление файлами +Name[rw]=Icunga ry'Idosiye +Name[se]=Fiilagieđaheapmi +Name[sk]=Správca súborov +Name[sl]=Upravljanje datotek +Name[sr]=Управљање фајловима +Name[sr@Latn]=Upravljanje fajlovima +Name[sv]=Filhantering +Name[ta]=கோப்பு மேலாண்மை +Name[te]=దస్త్ర నిర్వహణ +Name[tg]=Мудирияти файл +Name[th]=การจัดการแฟ้ม +Name[tr]=Dosya Yöneticisi +Name[tt]=Birem İdäräçe +Name[uk]=Керування файлами +Name[uz]=Fayl boshqaruvi +Name[uz@cyrillic]=Файл бошқаруви +Name[ven]=Malangulelel a Faela +Name[vi]=Quản lí Tập tin +Name[wa]=Manaedjî les fitchîs +Name[xh]=Uphatho Lwefayile +Name[zh_CN]=文件管理器 +Name[zh_TW]=檔案管理 +Name[zu]=Ukuphathwa kwamafayela +RootItem=Container0 +View1_LinkedView=true +View1_PassiveMode=true +View1_ServiceName=konq_sidebartng +View1_ServiceType=Browser/View +View1_ToggleView=true +View2_LinkedView=true +View2_PassiveMode=false +View2_ServiceName=konq_iconview +View2_ServiceType=inode/directory +View2_URL=$HOME diff --git a/konqueror/profile_filepreview.desktop b/konqueror/profile_filepreview.desktop new file mode 100644 index 000000000..36ef894f0 --- /dev/null +++ b/konqueror/profile_filepreview.desktop @@ -0,0 +1,110 @@ +[Profile] +Container0_Children=View1,Container2 +Container0_Orientation=Horizontal +Container0_SplitterSizes=166,866 +Container2_Children=View5,View6 +Container2_Orientation=Horizontal +Container2_SplitterSizes=295,493 +Height=550 +Name=File Preview +Name[af]=Lêer Voorskou +Name[ar]=معاينة الملف +Name[az]=Fayl Nümayişi +Name[be]=Прагляд файлаў +Name[bn]=ফাইল প্রাকদর্শন +Name[br]=Rakgwel restr +Name[bs]=Pregled datoteke +Name[ca]=Previsualitza el fitxer +Name[cs]=Náhled souboru +Name[csb]=Pòdzérk lopków +Name[cy]=Rhagolwg Ffeil +Name[da]=Filforhåndsvisning +Name[de]=Dateivorschau +Name[el]=Προεπισκόπηση αρχείων +Name[eo]=Dosierantaŭrigardo +Name[es]=Vista previa de archivo +Name[et]=Faili eelvaatlus +Name[eu]=Fitxategiaren aurrebista +Name[fa]=پیشنمایش پرونده +Name[fi]=Tiedoston esikatselu +Name[fr]=Aperçu de fichier +Name[fy]=Triem foarbyld +Name[ga]=Réamhamharc Comhaid +Name[gl]=Antevista de Arquivos +Name[he]=תצוגת קבצים מקדימה +Name[hi]=फ़ाइल पूर्वावलोकन +Name[hr]=Pregled datoteke +Name[hu]=Fájlkezelés előnézettel +Name[id]=Kilasan berkas +Name[is]=Prentsýn +Name[it]=Anteprima file +Name[ja]=ファイルプレビュー +Name[ka]=ფაილთა წინასწარ შეთვალიერება +Name[kk]=Файдарды алдын-ала қарау +Name[km]=មើលឯកសារជាមុន +Name[ko]=파일 미리보기 +Name[lo]=ສະແດງຕົວຢ່າງແຟ້ມ +Name[lt]=Bylų peržiūra +Name[lv]=Failu Apskate +Name[mk]=Преглед на датотеки +Name[mn]=Файл урьд. харах +Name[ms]=Prapapar Fail +Name[mt]=Previżjoni tal-Fajl +Name[nb]=Filvisning +Name[nds]=Datei-Vöransicht +Name[ne]=फाइल पूर्वावलोकन +Name[nl]=Bestandsvoorbeeld +Name[nn]=Filvising +Name[nso]=Ponelopele ya Faele +Name[pa]=ਫਾਇਲ਼ ਝਲਕ +Name[pl]=Podgląd plików +Name[pt]=Previsão de Ficheiros +Name[pt_BR]=Pré-visualização de arquivo +Name[ro]=Previzualizare fișiere +Name[ru]=Предварительный просмотр файлов +Name[rw]=Igaragazambere ry'Idosiye +Name[se]=Fiilačájeheapmi +Name[sk]=Prehliadanie súborov +Name[sl]=Datoteka za ogled +Name[sr]=Преглед фајлова +Name[sr@Latn]=Pregled fajlova +Name[sv]=Förhandsgranska fil +Name[ta]=கோப்பு முன்காட்சி +Name[te]=దస్త్ర ముందు వీక్షణ +Name[tg]=Пешнамоиши файл +Name[th]=แสดงตัวอย่างแฟ้ม +Name[tr]=Dosya Önizleme +Name[tt]=Birem Kürsätüçe +Name[uk]=Перегляд файлів +Name[uz]=Faylni koʻrib chiqish +Name[uz@cyrillic]=Файлни кўриб чиқиш +Name[ven]=Mbonelephanda ya Faela +Name[vi]=Xem trước Tập tin +Name[wa]=Prévoeyaedje des fitchîs +Name[xh]=Imboniselo yasekuqaleni Yefayile +Name[zh_CN]=文件预览 +Name[zh_TW]=檔案預覽 +Name[zu]=Umbukiso wangaphambili wefayela +RootItem=Container0 +View1_LinkedView=true +View1_LockedLocation=false +View1_PassiveMode=true +View1_ServiceName=konq_sidebartng +View1_ServiceType=Browser/View +View1_ToggleView=true +View1_URL=$HOME +View5_LinkedView=true +View5_LockedLocation=true +View5_PassiveMode=false +View5_ServiceName=konq_iconview +View5_ServiceType=inode/directory +View5_ToggleView=false +View5_URL=$HOME +View6_LinkedView=true +View6_LockedLocation=false +View6_PassiveMode=false +View6_ServiceName=katepart +View6_ServiceType=text/plain +View6_ToggleView=false +View6_URL= +Width=800 diff --git a/konqueror/profile_kde_devel.desktop b/konqueror/profile_kde_devel.desktop new file mode 100644 index 000000000..59c9dd650 --- /dev/null +++ b/konqueror/profile_kde_devel.desktop @@ -0,0 +1,112 @@ +[Profile] +FullScreen=false +Name=KDE Development +Name[af]=KDE Ontwikkeling +Name[ar]=تطوير KDE +Name[az]=KDE İnkişafı +Name[be]=Распрацоўка KDE +Name[bn]=কে.ডি.ই. ডেভেলপমেন্ট +Name[bs]=KDE programiranje +Name[ca]=Desenvolupament KDE +Name[cs]=Vývoj KDE +Name[csb]=Rozwij KDE +Name[cy]=Datblygu KDE +Name[da]=KDE-Udvikling +Name[de]=KDE-Entwicklung +Name[el]=Ανάπτυξη του KDE +Name[eo]=KDE-Programado +Name[es]=Desarrollo de KDE +Name[et]=KDE arendus +Name[eu]=KDEren garapena +Name[fa]=توسعۀ KDE +Name[fi]=KDE:n kehitystyökalut +Name[fr]=Développement de KDE +Name[fy]=KDE-ûntwikkeling +Name[ga]=Forbairt KDE +Name[gl]=Desenvolvemento de KDE +Name[he]=פיתוח של KDE +Name[hi]=केडीई डेवलपमेंट +Name[hr]=KDE razvoj +Name[hu]=KDE-s fejlesztés +Name[is]=KDE þróun +Name[it]=Sviluppo KDE +Name[ja]=KDE 開発 +Name[ka]=KDE-ში პროგრამირება +Name[kk]=KDE жүйесін жетілдіру +Name[km]=ការអភិវឌ្ឍន៍ KDE +Name[ko]=KDE 개발 +Name[lt]=KDE vystymas +Name[lv]=KDE Izstrāde +Name[mk]=Развој на KDE +Name[ms]=Pembangunan KDE +Name[mt]=Żvilupp KDE +Name[nb]=KDE-utvikling +Name[nds]=KDE-Utwickeln +Name[ne]=KDE विकास +Name[nl]=KDE-ontwikkeling +Name[nn]=KDE-utvikling +Name[pa]=KDE ਵਿਕਾਸ +Name[pl]=Rozwijanie KDE +Name[pt]=Desenvolvimento do KDE +Name[pt_BR]=Desenvolvimento do KDE +Name[ro]=Dezvoltare KDE +Name[ru]=Разработка в KDE +Name[rw]=KDE Ikoraporogaramu +Name[se]=KDE-ovdánahttin +Name[sk]=Vývoj KDE +Name[sl]=Razvoj KDE +Name[sr]=KDE развој +Name[sr@Latn]=KDE razvoj +Name[sv]=KDE-utveckling +Name[ta]=KDE உருவாக்கம் +Name[te]=కెడిఈ డెవలప్ మెంట్ +Name[th]=พัฒนาโปรแกรม KDE +Name[tr]=KDE Geliştirme +Name[tt]=KDE Citeşterü +Name[uk]=Розробка KDE +Name[uz]=KDE uchun dasturlashtirish +Name[uz@cyrillic]=KDE учун дастурлаштириш +Name[vi]=Phát triển KDE +Name[wa]=Diswalpaedje KDE +Name[zh_CN]=KDE 开发 +Name[zh_TW]=KDE 程式開發 +RootItem=Tabs0 +Tabs0_Children=ViewT0,ViewT1,ViewT2,ViewT3,ViewT4 +Tabs0_activeChildIndex=0 +ViewT0_LinkedView=false +ViewT0_LockedLocation=false +ViewT0_PassiveMode=false +ViewT0_ServiceName=khtml +ViewT0_ServiceType=text/html +ViewT0_ToggleView=false +ViewT0_URL=http://api.kde.org/ +ViewT1_LinkedView=false +ViewT1_LockedLocation=false +ViewT1_PassiveMode=false +ViewT1_ServiceName=khtml +ViewT1_ServiceType=text/html +ViewT1_ToggleView=false +ViewT1_URL=http://doc.trolltech.com/ +ViewT2_LinkedView=false +ViewT2_LockedLocation=false +ViewT2_PassiveMode=false +ViewT2_ServiceName=khtml +ViewT2_ServiceType=text/html +ViewT2_ToggleView=false +ViewT2_URL=http://bugs.kde.org/ +ViewT3_LinkedView=false +ViewT3_LockedLocation=false +ViewT3_PassiveMode=false +ViewT3_ServiceName=khtml +ViewT3_ServiceType=text/html +ViewT3_ToggleView=false +ViewT3_URL=man:/gcc +ViewT4_LinkedView=false +ViewT4_LockedLocation=false +ViewT4_PassiveMode=false +ViewT4_ServiceName=khtml +ViewT4_ServiceType=text/html +ViewT4_ToggleView=false +ViewT4_URL=info:/dir +Width=80% +Height=80% diff --git a/konqueror/profile_midnightcommander.desktop b/konqueror/profile_midnightcommander.desktop new file mode 100644 index 000000000..12dbb442d --- /dev/null +++ b/konqueror/profile_midnightcommander.desktop @@ -0,0 +1,45 @@ +[Profile] +Container0_Children=Container1,View2 +Container0_Orientation=Vertical +Container0_SplitterSizes=481,87 +Container1_Children=View3,View4 +Container1_Orientation=Horizontal +Container1_SplitterSizes=100,100 +Height=658 +Name=Midnight Commander +Name[bn]=মিডনাইট কমান্ডার +Name[eo]=Meznokta komandanto +Name[fa]=فرماندۀ نیمهشب +Name[hi]=मिडनाइट कमांडर +Name[km]=ពាក្យបញ្ជា Midnight +Name[ko]=미드나잇 커맨더 +Name[lo]=ມິດໄນຄອມມານເດີ +Name[lv]=Pusnakts Komandieris +Name[ms]=Pemberi Arahan Tengah Malam +Name[ne]=मिडनाइट आदेश +Name[nso]=Molaedi wa Bosegogare +Name[pa]=ਮਿਡਨਾਇਟ ਕਮਾਂਡਰ +Name[rw]=Mutangabwiriza Hagati-Ijoro +Name[ta]=நடு இரவு கட்டளை +Name[tg]=Фармондиҳандаи нимаи шаб +Name[th]=มิดไนท์คอมมานเดอร์ +Name[ven]=Muhulwane wa vhukati ha vhusiku +Name[xh]=Umyaleli Waphakathi kobusuku +Name[zu]=Umyaleli waphakathi nobusuku +RootItem=Container0 +View2_LinkedView=true +View2_PassiveMode=false +View2_ServiceName=konsolepart +View2_ServiceType=Browser/View +View2_ToggleView=true +View3_LinkedView=false +View3_PassiveMode=false +View3_ServiceName=konq_detailedlistview +View3_ServiceType=inode/directory +View3_ToggleView=false +View4_LinkedView=false +View4_PassiveMode=false +View4_ServiceName=konq_detailedlistview +View4_ServiceType=inode/directory +View4_ToggleView=false +Width=600 diff --git a/konqueror/profile_simplebrowser.desktop b/konqueror/profile_simplebrowser.desktop new file mode 100644 index 000000000..5fe8c59c2 --- /dev/null +++ b/konqueror/profile_simplebrowser.desktop @@ -0,0 +1,79 @@ +[Profile] +Name=Simple Browser +Name[af]=Eenvoudige Blaaier +Name[ar]=متصفح بسيط +Name[az]=Sadə Səyyah +Name[be]=Звычайны вандроўнік +Name[bn]=সরল ব্রাউজার +Name[bs]=Jednostavan web preglednik +Name[ca]=Navegador senzill +Name[cs]=Jednoduchý prohlížeč +Name[csb]=Prosti przezérnik +Name[cy]=Porydd Syml +Name[da]=Simpel browser +Name[de]=Einfacher Browser +Name[el]=Απλός περιηγητής ιστού +Name[eo]=Simpla TTT-legilo +Name[es]=Navegador sencillo +Name[et]=Lihtne brauser +Name[eu]=Web arakatzaile erraza +Name[fa]=مرورگر ساده +Name[fi]=Yksinkertainen selain +Name[fr]=Navigateur simple +Name[fy]=Ienfâldige blêder +Name[ga]=Brabhsálaí Simplí +Name[gl]=Navegador Sinxelo +Name[he]=דפדפן פשוט +Name[hi]=सादा ब्राउज़र +Name[hr]=Jednostavni preglednik +Name[hu]=Egyszerű böngésző +Name[is]=Einfaldur vafri +Name[it]=Browser semplice +Name[ja]=簡易ブラウザ +Name[ka]=მარტივი ბრაუზერი +Name[kk]=Жеңіл браузер +Name[km]=កម្មវិធីរុករកសាមញ្ញ +Name[ko]=간단한 탐색기 +Name[lt]=Paprasta naršyklė +Name[lv]=Vienkāršs pārlūks +Name[mk]=Едноставен прелистувач +Name[ms]=Pelayar Mudah +Name[mt]=Browser Sempliċi +Name[nb]=Enkel nettleser +Name[nds]=Eenfach Nettkieker +Name[ne]=सामान्य ब्राउजर +Name[nl]=Eenvoudige browser +Name[nn]=Enkel nettlesar +Name[pa]=ਸਧਾਰਨ ਝਲਕਾਰਾ +Name[pl]=Prosta przeglądarka +Name[pt]=Navegação Simples +Name[pt_BR]=Navegador Web Simples +Name[ro]=Navigare simplă +Name[ru]=Простой браузер +Name[rw]=Mucukumubuzi Yoroheje +Name[se]=Oktageardánis fierpmádatlogan +Name[sk]=Jednoduchý prehliadač +Name[sl]=Preprost brskalnik +Name[sr]=Једноставан прегледач +Name[sr@Latn]=Jednostavan pregledač +Name[sv]=Enkel webbläsning +Name[ta]=எளிய உலாவி +Name[te]=సరళ బ్రౌజర్ +Name[tg]=Браузери осон +Name[th]=โปรแกรมท่องเว็บแบบเรียบง่าย +Name[tr]=Sade Tarayıcı +Name[tt]=Ciñel Browser +Name[uk]=Простий навігатор +Name[uz]=Oddiy veb-brauzer +Name[uz@cyrillic]=Оддий веб-браузер +Name[vi]=Trình duyệt Đơn giản +Name[wa]=Betchteu waibe simpe +Name[zh_CN]=简单浏览器 +Name[zh_TW]=簡易瀏覽器 +XMLUIFile=konq-simplebrowser.rc +RootItem=View0 +View0_ServiceName=konq_aboutpage +View0_ServiceType=KonqAboutPage +View0_URL=about:konqueror +Width=60% +Height=80% diff --git a/konqueror/profile_tabbedbrowsing.desktop b/konqueror/profile_tabbedbrowsing.desktop new file mode 100644 index 000000000..38cc09e3c --- /dev/null +++ b/konqueror/profile_tabbedbrowsing.desktop @@ -0,0 +1,106 @@ +[Profile] +FullScreen=false +Name=Tabbed Browsing +Name[af]=Oortjie Blaaier +Name[ar]=التصفح المبوب +Name[az]=Səkməli Səyyah +Name[be]=Вандроўка з укладкамі +Name[bn]=ট্যাব সম্বলিত ব্রাউজিং +Name[br]=Furchal gant bevennigoù +Name[bs]=Pregled weba sa tabovima +Name[ca]=Navegació amb pestanyes +Name[cs]=Prohlížení se záložkami +Name[csb]=Przezéranié kartama +Name[cy]=Pori Tabiedig +Name[da]=Fanebladssøgning +Name[de]=Browsing mit Unterfenstern +Name[el]=Περιήγηση με καρτέλες +Name[eo]=langeta foliumado +Name[es]=Navegación con solapas +Name[et]=Kaartidega lehitsemine +Name[eu]=Fitxa bitarteko arakaketa +Name[fa]=مرورگر تبشده +Name[fi]=Välilehdillä varustettu selain +Name[fr]=Navigation par onglets +Name[fy]=Blêder mei ljeppers +Name[ga]=Brabhsáil le Cluaisíní +Name[gl]=Navegación con Pestanas +Name[he]=גלישה בכרטיסיות +Name[hi]=टैब्ड ब्राउज़िंग +Name[hr]=Pregledavanje u karticama +Name[hu]=Lapozós böngésző +Name[is]=Flipað flak +Name[it]=Navigazione a schede +Name[ja]=タブブラウズ +Name[ka]=დაფებზე ჩვენება +Name[kk]=Қойындылы браузер +Name[km]=ការរុករកជាផ្ទាំង +Name[ko]=탭 브라우징 +Name[lt]=Naršymas kortelėse +Name[lv]=Tabota pārlūkošana +Name[mk]=Прелистување со ливчиња +Name[ms]=Pelayaran Bertab +Name[mt]=Browsing bit-tabs +Name[nb]=Nettleser med faner +Name[nds]=Nettkieken mit Paneels +Name[ne]=ट्याब गरिएको ब्राउजिङ +Name[nl]=Browser met tabbladen +Name[nn]=Nettlesar med faner +Name[pa]=ਟੈਬ ਝਲਕੀ +Name[pl]=Przeglądanie wielu stron w jednym oknie +Name[pt]=Navegação por Páginas +Name[pt_BR]=Navegação em Abas +Name[ro]=Navigare cu subferestre +Name[ru]=Браузер с вкладками +Name[rw]=Icukumbura rifite Udufishifi +Name[se]=Fierpmádatlogan mas leat gilkorat +Name[sk]=Prehliadač s kartami +Name[sl]=Brskanje v zavihkih +Name[sr]=Прегледање са језичцима +Name[sr@Latn]=Pregledanje sa jezičcima +Name[sv]=Webbläsning med flikar +Name[ta]=தத்தும் உலாவி +Name[te]=టాబ్ బ్రౌజింగ్ +Name[th]=ท่องเว็บแบบใช้แท็บ +Name[tr]=Sekmeli Tarama +Name[tt]=Tabaqlı Browser +Name[uk]=Навігація з вкладками +Name[uz]=Tabli veb koʻrish +Name[uz@cyrillic]=Табли веб кўриш +Name[vi]=Duyệt bằng cách chuyển Thẻ +Name[wa]=Naiviaedje waibe avou des linwetes +Name[zh_CN]=标签式浏览 +Name[zh_TW]=分頁瀏覽 +RootItem=Tabs0 +Tabs0_Children=ViewT0,ViewT1,ViewT2,ViewT3 +Tabs0_activeChildIndex=0 +ViewT0_LinkedView=false +ViewT0_LockedLocation=false +ViewT0_PassiveMode=false +ViewT0_ServiceName=khtml +ViewT0_ServiceType=text/html +ViewT0_ToggleView=false +ViewT0_URL=http://www.kde.org/ +ViewT1_LinkedView=false +ViewT1_LockedLocation=false +ViewT1_PassiveMode=false +ViewT1_ServiceName=khtml +ViewT1_ServiceType=text/html +ViewT1_ToggleView=false +ViewT1_URL=http://dot.kde.org/ +ViewT2_LinkedView=false +ViewT2_LockedLocation=false +ViewT2_PassiveMode=false +ViewT2_ServiceName=khtml +ViewT2_ServiceType=text/html +ViewT2_ToggleView=false +ViewT2_URL=http://themes.kde.org/ +ViewT3_LinkedView=false +ViewT3_LockedLocation=false +ViewT3_PassiveMode=false +ViewT3_ServiceName=khtml +ViewT3_ServiceType=text/html +ViewT3_ToggleView=false +ViewT3_URL=http://www.kde-apps.org/ +Width=80% +Height=80% diff --git a/konqueror/profile_webbrowsing.desktop b/konqueror/profile_webbrowsing.desktop new file mode 100644 index 000000000..51b99d8d1 --- /dev/null +++ b/konqueror/profile_webbrowsing.desktop @@ -0,0 +1,86 @@ +[Profile] +Name=Web Browsing +Name[af]=Web Blaaier +Name[ar]=تصفح الشبكة +Name[az]=Veb Gəzintisi +Name[be]=Вандроўка па Сеціве +Name[bn]=ওয়েব ব্রাউজিং +Name[br]=Furchal ar Gwiad +Name[bs]=Pretraživanje weba +Name[ca]=Navegació Web +Name[cs]=Prohlížení internetu +Name[csb]=Przezéranié sécë +Name[cy]=Pori'r W? +Name[da]=Netsøgning +Name[de]=Webbrowser +Name[el]=Περιήγηση ιστού +Name[eo]=TTTumado +Name[es]=Navegación en Web +Name[et]=Veebi lehitsemine +Name[eu]=Web arakaketa +Name[fa]=مرورگر وب +Name[fi]=WWW-selailu +Name[fr]=Navigation web +Name[fy]=Webblêdzje +Name[ga]=Brabhsáil Lín +Name[gl]=Navegación Web +Name[he]=גלישה באינטרנט +Name[hi]=वेब ब्राउजिंग +Name[hr]=Pregledavanje Interneta +Name[hu]=Webböngésző +Name[id]=Menjelajahi Web +Name[is]=Flakk um vefinn +Name[it]=Navigazione Web +Name[ja]=ウェブ閲覧 +Name[ka]=ვების ჩვენება +Name[kk]=Веб браузер +Name[km]=ការរុករកបណ្ដាញ +Name[ko]=웹 브라우징 +Name[lo]=ຮງກເບິ່ງເວ໊ບເພຈ +Name[lt]=Žiniatinklio naršymas +Name[lv]=Tīmekļa Pārlūkošana +Name[mk]=Веб-прелистување +Name[mn]=Вэб-Хөтөч +Name[ms]=Pelayaran Web +Name[nb]=Nettlesing +Name[nds]=Nettkieken +Name[ne]=वेब ब्राउजिङ +Name[nl]=Webbrowsen +Name[nn]=Vevsurfing +Name[nso]=Boinyakisi bja Web +Name[oc]=Navigacion Oeb +Name[pa]=ਵੈੱਬ ਝਲਕ +Name[pl]=Przeglądanie sieci +Name[pt]=Navegação Web +Name[pt_BR]=Navegação Web +Name[ro]=Navigare WEB +Name[ru]=Веб-браузер +Name[rw]=Icukumbura ry'Urubugamakuru +Name[se]=Fierpmádatgolgadeapmi +Name[sk]=Web prehliadanie +Name[sl]=Brskanje po spletu +Name[sr]=Прегледање Веба +Name[sr@Latn]=Pregledanje Veba +Name[sv]=Webbläsning +Name[ta]=வலை உலாவி +Name[te]=వెబ్ బ్రౌజింగ్ +Name[tg]=Тафсири Вэб +Name[th]=เรียกดูเว็บ +Name[tr]=Web Tarama +Name[tt]=Web Küzätü +Name[uk]=Навігація Тенет +Name[uz]=Veb koʻrish +Name[uz@cyrillic]=Веб кўриш +Name[ven]=Burausini ya Webu +Name[vi]=Duyệt Mạng +Name[wa]=Naiviaedje waibe +Name[xh]=Ukhangelo lwencwadi ze Web +Name[zh_CN]=Web 浏览 +Name[zh_TW]=網頁瀏覽 +Name[zu]=Ukucinga kwi-Web +RootItem=View0 +View0_ServiceName=konq_aboutpage +View0_ServiceType=KonqAboutPage +View0_URL=about:konqueror +Width=80% +Height=80% diff --git a/konqueror/quickprint/Makefile.am b/konqueror/quickprint/Makefile.am new file mode 100644 index 000000000..81887b84b --- /dev/null +++ b/konqueror/quickprint/Makefile.am @@ -0,0 +1,7 @@ +konqservice_DATA = text-print.desktop text-html-print.desktop text-css-print.desktop \ + text-ada-print.desktop text-c++-print.desktop text-c++h-print.desktop \ + text-ch-print.desktop text-diff-print.desktop text-java-print.desktop \ + text-log-print.desktop text-makefile-print.desktop text-pas-print.desktop \ + text-perl-print.desktop text-python-print.desktop text-tcl-print.desktop \ + text-tex-print.desktop text-xslt-print.desktop text-xml-print.desktop +konqservicedir = $(kde_datadir)/konqueror/servicemenus diff --git a/konqueror/quickprint/TODO b/konqueror/quickprint/TODO new file mode 100644 index 000000000..511114aa9 --- /dev/null +++ b/konqueror/quickprint/TODO @@ -0,0 +1,18 @@ +- make small programms to print the files and other data better + - printing text + - you can enable for example syntaxhighlighting + - printing pictures (I think that can go than to the kdegraphics package) + - set the position of the picture on the site and something like that + - printing html (homepges) + - print the html code like for the textprinting + - print the html file like it was parsed with khtml + - printing TeX documents with a action on the TeX source + - I don't know at the moment options for that + - ... + and something like that ;) + +If we have small programms for that printing things we have no longer the question +from kprinter to convert the text/picture or not. + +If somebody ont to add some other things to this TODO list we can make step by step +a compleate list of parser for printing. ;) diff --git a/konqueror/quickprint/text-ada-print.desktop b/konqueror/quickprint/text-ada-print.desktop new file mode 100644 index 000000000..74f9acb7a --- /dev/null +++ b/konqueror/quickprint/text-ada-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-adasrc +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-c++-print.desktop b/konqueror/quickprint/text-c++-print.desktop new file mode 100644 index 000000000..311d214b3 --- /dev/null +++ b/konqueror/quickprint/text-c++-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-c++src +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-c++h-print.desktop b/konqueror/quickprint/text-c++h-print.desktop new file mode 100644 index 000000000..4ae52ca22 --- /dev/null +++ b/konqueror/quickprint/text-c++h-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-c++hdr +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-c-print.desktop b/konqueror/quickprint/text-c-print.desktop new file mode 100644 index 000000000..0dfb482fb --- /dev/null +++ b/konqueror/quickprint/text-c-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-csrc +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-ch-print.desktop b/konqueror/quickprint/text-ch-print.desktop new file mode 100644 index 000000000..373cc2df8 --- /dev/null +++ b/konqueror/quickprint/text-ch-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-chdr +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-css-print.desktop b/konqueror/quickprint/text-css-print.desktop new file mode 100644 index 000000000..9e05d8886 --- /dev/null +++ b/konqueror/quickprint/text-css-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/css +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-diff-print.desktop b/konqueror/quickprint/text-diff-print.desktop new file mode 100644 index 000000000..7f85c4585 --- /dev/null +++ b/konqueror/quickprint/text-diff-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-diff +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-html-print.desktop b/konqueror/quickprint/text-html-print.desktop new file mode 100644 index 000000000..0be07c3bf --- /dev/null +++ b/konqueror/quickprint/text-html-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/html +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-java-print.desktop b/konqueror/quickprint/text-java-print.desktop new file mode 100644 index 000000000..a6563212b --- /dev/null +++ b/konqueror/quickprint/text-java-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-java +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-log-print.desktop b/konqueror/quickprint/text-log-print.desktop new file mode 100644 index 000000000..b524d6488 --- /dev/null +++ b/konqueror/quickprint/text-log-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-log +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-makefile-print.desktop b/konqueror/quickprint/text-makefile-print.desktop new file mode 100644 index 000000000..886bb3b3a --- /dev/null +++ b/konqueror/quickprint/text-makefile-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-makefile +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-pas-print.desktop b/konqueror/quickprint/text-pas-print.desktop new file mode 100644 index 000000000..075c5cb65 --- /dev/null +++ b/konqueror/quickprint/text-pas-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-pascal +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-perl-print.desktop b/konqueror/quickprint/text-perl-print.desktop new file mode 100644 index 000000000..cb0305c6c --- /dev/null +++ b/konqueror/quickprint/text-perl-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-perl +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-print.desktop b/konqueror/quickprint/text-print.desktop new file mode 100644 index 000000000..8ec33665d --- /dev/null +++ b/konqueror/quickprint/text-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/plain +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-python-print.desktop b/konqueror/quickprint/text-python-print.desktop new file mode 100644 index 000000000..d439f3ed0 --- /dev/null +++ b/konqueror/quickprint/text-python-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-python +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-tcl-print.desktop b/konqueror/quickprint/text-tcl-print.desktop new file mode 100644 index 000000000..4914f1edb --- /dev/null +++ b/konqueror/quickprint/text-tcl-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-tcl +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-tex-print.desktop b/konqueror/quickprint/text-tex-print.desktop new file mode 100644 index 000000000..3cc4f9493 --- /dev/null +++ b/konqueror/quickprint/text-tex-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-tex +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-xml-print.desktop b/konqueror/quickprint/text-xml-print.desktop new file mode 100644 index 000000000..b559d2fbe --- /dev/null +++ b/konqueror/quickprint/text-xml-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-xml +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/quickprint/text-xslt-print.desktop b/konqueror/quickprint/text-xslt-print.desktop new file mode 100644 index 000000000..c0ac5cb82 --- /dev/null +++ b/konqueror/quickprint/text-xslt-print.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +ServiceTypes=text/x-xslt +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[ka]=ბეჭდვა... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[ko]=인쇄... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut … +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut … +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipărește... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Bosib chiqarish +Name[uz@cyrillic]=Босиб чиқариш +Name[vi]=In ấn... +Name[wa]=Rexhe... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/konqueror/remoteencodingplugin/Makefile.am b/konqueror/remoteencodingplugin/Makefile.am new file mode 100644 index 000000000..e80195dcb --- /dev/null +++ b/konqueror/remoteencodingplugin/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES= -I$(top_srcdir)/libkonq $(all_includes) +METASOURCES=AUTO + +kde_module_LTLIBRARIES = konq_remoteencoding.la +konq_remoteencoding_la_SOURCES = kremoteencodingplugin.cpp +konq_remoteencoding_la_LIBADD = $(top_builddir)/libkonq/libkonq.la +konq_remoteencoding_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) + +iconviewdir = $(kde_datadir)/konqiconview/kpartplugins +iconview_DATA = kremoteencodingplugin.rc kremoteencodingplugin.desktop + +listviewdir = $(kde_datadir)/konqlistview/kpartplugins +listview_DATA = kremoteencodingplugin.rc kremoteencodingplugin.desktop diff --git a/konqueror/remoteencodingplugin/kremoteencodingplugin.cpp b/konqueror/remoteencodingplugin/kremoteencodingplugin.cpp new file mode 100644 index 000000000..b771b0a09 --- /dev/null +++ b/konqueror/remoteencodingplugin/kremoteencodingplugin.cpp @@ -0,0 +1,266 @@ +/* + Copyright (c) 2003 Thiago Macieira <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License (LGPL) 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. +*/ + +/* + * This code is largely based on the UserAgent changer plugin (uachanger) + * Copyright © 2001 Dawit Alemayehu <[email protected]> + * Distributed under the same terms. + */ + +#include <kdebug.h> +#include <kaction.h> +#include <klocale.h> +#include <kglobal.h> +#include <kconfig.h> +#include <kcharsets.h> +#include <kpopupmenu.h> +#include <dcopclient.h> +#include <kgenericfactory.h> +#include <kprotocolmanager.h> +#include <kprotocolinfo.h> +#include <kio/slaveconfig.h> +#include <konq_dirpart.h> +#include <kparts/browserextension.h> + +#include "kremoteencodingplugin.h" + +#define DATA_KEY QString::fromLatin1("Charset") + +KRemoteEncodingPlugin::KRemoteEncodingPlugin(QObject * parent, + const char *name, + const QStringList &) + : KParts::Plugin(parent, name), m_loaded(false), m_idDefault(0) +{ + m_menu = new KActionMenu(i18n("Select Remote Charset"), "charset", + actionCollection(), "changeremoteencoding"); + connect(m_menu->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotAboutToShow())); + m_menu->setEnabled(false); + m_menu->setDelayed(false); + + m_part = dynamic_cast<KonqDirPart*>(parent); + if (m_part) + // if parent is not a KonqDirPart, our menu will never show + QObject::connect(m_part, SIGNAL(aboutToOpenURL()), + this, SLOT(slotAboutToOpenURL())); +} + +KRemoteEncodingPlugin::~KRemoteEncodingPlugin() +{ +} + +void +KRemoteEncodingPlugin::slotReload() +{ + loadSettings(); +} + +void +KRemoteEncodingPlugin::loadSettings() +{ + m_loaded = true; + + m_encodingDescriptions = KGlobal::charsets()->descriptiveEncodingNames(); + + fillMenu(); +} + +void +KRemoteEncodingPlugin::slotAboutToOpenURL() +{ + KURL oldURL = m_currentURL; + m_currentURL = m_part->url(); + + if (m_currentURL.protocol() != oldURL.protocol()) + { + // This plugin works on ftp, fish, etc. + // everything whose type is T_FILESYSTEM except for local files + if (!m_currentURL.isLocalFile() && + KProtocolInfo::outputType(m_currentURL) == KProtocolInfo::T_FILESYSTEM) + { + m_menu->setEnabled(true); + loadSettings(); + } + else + m_menu->setEnabled(false); + + return; + } + + if (m_currentURL.host() != oldURL.host()) + updateMenu(); +} + +void +KRemoteEncodingPlugin::fillMenu() +{ + KPopupMenu *menu = m_menu->popupMenu(); + menu->clear(); + + QStringList::ConstIterator it; + int count = 0; + for (it = m_encodingDescriptions.begin(); it != m_encodingDescriptions.end(); ++it) + menu->insertItem(*it, this, SLOT(slotItemSelected(int)), 0, ++count); + menu->insertSeparator(); + + menu->insertItem(i18n("Reload"), this, SLOT(slotReload()), 0, ++count); + menu->insertItem(i18n("Default"), this, SLOT(slotDefault()), 0, ++count); + m_idDefault = count; +} + +void +KRemoteEncodingPlugin::updateMenu() +{ + if (!m_loaded) + loadSettings(); + + // uncheck everything + for (unsigned i = 0; i < m_menu->popupMenu()->count(); i++) + m_menu->popupMenu()->setItemChecked(m_menu->popupMenu()->idAt(i), false); + + QString charset = KIO::SlaveConfig::self()->configData(m_currentURL.protocol(), m_currentURL.host(), + DATA_KEY); + if (!charset.isEmpty()) + { + int id = 1; + QStringList::Iterator it; + for (it = m_encodingDescriptions.begin(); it != m_encodingDescriptions.end(); ++it, ++id) + if ((*it).find(charset) != -1) + break; + + kdDebug() << k_funcinfo << "URL=" << m_currentURL << " charset=" << charset << endl; + + if (it == m_encodingDescriptions.end()) + kdWarning() << k_funcinfo << "could not find entry for charset=" << charset << endl; + else + m_menu->popupMenu()->setItemChecked(id, true); + } + else + m_menu->popupMenu()->setItemChecked(m_idDefault, true); +} + +void +KRemoteEncodingPlugin::slotAboutToShow() +{ + if (!m_loaded) + loadSettings(); + updateMenu(); +} + +void +KRemoteEncodingPlugin::slotItemSelected(int id) +{ + KConfig config(("kio_" + m_currentURL.protocol() + "rc").latin1()); + QString host = m_currentURL.host(); + + if (!m_menu->popupMenu()->isItemChecked(id)) + { + QString charset = KGlobal::charsets()->encodingForName(m_encodingDescriptions[id - 1]); + + config.setGroup(host); + config.writeEntry(DATA_KEY, charset); + config.sync(); + + // Update the io-slaves... + updateBrowser(); + } +} + +void +KRemoteEncodingPlugin::slotDefault() +{ + // We have no choice but delete all higher domain level + // settings here since it affects what will be matched. + KConfig config(("kio_" + m_currentURL.protocol() + "rc").latin1()); + + QStringList partList = QStringList::split('.', m_currentURL.host(), false); + if (!partList.isEmpty()) + { + partList.remove(partList.begin()); + + QStringList domains; + // Remove the exact name match... + domains << m_currentURL.host(); + + while (partList.count()) + { + if (partList.count() == 2) + if (partList[0].length() <= 2 && partList[1].length() == 2) + break; + + if (partList.count() == 1) + break; + + domains << partList.join("."); + partList.remove(partList.begin()); + } + + for (QStringList::Iterator it = domains.begin(); it != domains.end(); + it++) + { + kdDebug() << k_funcinfo << "Domain to remove: " << *it << endl; + if (config.hasGroup(*it)) + config.deleteGroup(*it); + else if (config.hasKey(*it)) + config.deleteEntry(*it); + } + } + config.sync(); + + // Update the io-slaves. + updateBrowser(); +} + +void +KRemoteEncodingPlugin::updateBrowser() +{ + // Inform running io-slaves about the change... + DCOPClient *client = new DCOPClient(); + + if (!client->attach()) + kdDebug() << "Can't connect with DCOP server." << endl; + + QByteArray data; + QDataStream stream(data, IO_WriteOnly); + stream << QString::null; + // use call to make sure reparsing is done before reloading the url + QCStringList apps = client->registeredApplications(); + for( QCStringList::ConstIterator it = apps.begin(); + it != apps.end(); + ++it ) + { + QCString rtype; + QByteArray rdata; + client->call( *it, "KIO::Scheduler", "reparseSlaveConfiguration(QString)", + data, rtype, rdata); + } + delete client; + + // Reload the page with the new charset + KParts::URLArgs args = m_part->extension()->urlArgs(); + args.reload = true; + m_part->extension()->setURLArgs(args); + m_part->openURL(m_currentURL); +} + +typedef KGenericFactory < KRemoteEncodingPlugin > KRemoteEncodingPluginFactory; +K_EXPORT_COMPONENT_FACTORY(konq_remoteencoding, + KRemoteEncodingPluginFactory("kremoteencodingplugin")) +#include "kremoteencodingplugin.moc" diff --git a/konqueror/remoteencodingplugin/kremoteencodingplugin.desktop b/konqueror/remoteencodingplugin/kremoteencodingplugin.desktop new file mode 100644 index 000000000..397654bef --- /dev/null +++ b/konqueror/remoteencodingplugin/kremoteencodingplugin.desktop @@ -0,0 +1,135 @@ +[Desktop Entry] +Type=Service +X-KDE-PluginInfo-Author=Thiago Macieira +X-KDE-PluginInfo-Name=kremoteencodingplugin +X-KDE-PluginInfo-Version=3.4 +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category=Tools +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-ParentApp=konqueror +Icon=charset +Name=Remote Encoding Plugin +Name[af]=Afgeleë Enkodering Inprop Module +Name[ar]=قابس الترميز البعيد +Name[be]=Утулка аддаленага знаказбору +Name[bg]=Отдалечена кодова таблица +Name[bn]=দূরবর্তী এনকোডিং প্লাগ-ইন +Name[bs]=Dodatak za udaljeno kodiranje +Name[ca]=Endollable de codificació remota +Name[cs]=Modul vzdáleného kódování +Name[csb]=Plugins daleczégò kòdowaniô +Name[da]=Plugin for fjernkodning +Name[de]=Modul für entfernte Kodierung +Name[el]=Πρόσθετο απομακρυσμένης κωδικοποίησης +Name[eo]=Fora kodoprezento Kromaĵo +Name[es]=Complemento de codificación remota +Name[et]=Võrgukodeeringu plugin +Name[eu]=Urruneko kodeketa plugina +Name[fa]=وصلۀ کدبندی دور +Name[fi]=Etämerkinmuunnosliitännäinen +Name[fr]=Module d'encodage distant +Name[fy]=Eksterne-kodearringsplugin +Name[gl]=Plugin de Codificación Remota +Name[he]=תוסף קידוד מרוחק +Name[hr]=Dodatak za udaljeno kodiranje +Name[hu]=Távoli kódolás modul +Name[is]=Fjarlægt kóðunaríforrit +Name[it]=Plugin codifica remota +Name[ja]=リモートエンコーディングプラグイン +Name[ka]=კოდირების დაშორებული მოდული +Name[kk]=Қашықтан баптау +Name[km]=កម្មវិធីជំនួយការអ៊ិនកូដពីចម្ងាយ +Name[ko]=원격 인코딩 플러그인 +Name[lt]=Nutolusių vietų koduotės priedas +Name[mk]=Приклучок за оддалечено кодирање +Name[ms]=Plugin Pengekodan Jauh +Name[nb]=Eksterne kodingsprogramtillegg +Name[nds]=Plugin för feern Koderen +Name[ne]=टाढा सङ्केतन प्लगइन +Name[nl]=Externe-coderingsplugin +Name[nn]=Eksterne kodingsprogramtillegg +Name[pa]=ਰਿਮੋਟ ਇੰਕੋਡਿੰਗ ਪਲੱਗਇਨ +Name[pl]=Wtyczka zdalnego kodowania +Name[pt]='Plugin' de Codificação Remota +Name[pt_BR]=Plug-in de Codificação Remota +Name[ro]=Plugin de încodare la distanță +Name[ru]=Кодировка имён файлов на сервере +Name[rw]=Icomeka Gusobeka bya Kure +Name[se]=Gáiddus koden lassemoduvla +Name[sk]=Modul pre šifrovanie +Name[sl]=Vstavek Oddaljeno kodiranje +Name[sr]=Прикључак за удаљено кодирање +Name[sr@Latn]=Priključak za udaljeno kodiranje +Name[sv]=Insticksprogram för fjärrkodning +Name[ta]=தொலைதூர குறியீட்டு சொருகுப்பொருள் +Name[th]=ปลั๊กอินเข้ารหัสทางไกล +Name[tr]=Uzaktan Şifreleme Eklentisi +Name[uk]=Втулок віддаленого кодування +Name[vi]=Trình bổ sung Mã hoá Trên mạng +Name[wa]=Tchôke-divins d' ecôdaedje å lon +Name[zh_CN]=远程编码插件 +Name[zh_TW]=遠端編碼外掛程式 +Comment=Remote Encoding Plugin for Konqueror +Comment[af]=Afgeë enkodering inprop module vir Konqueror +Comment[ar]=قابس الترميز البعيد لِــ Konqueror +Comment[be]=Утулка аддаленага знаказбору для Konqueror +Comment[bg]=Приставка за отдалечена кодова таблица на браузъра +Comment[bn]=কনকরার-এর জন্য দূরবর্তী এনকোডিং প্লাগ-ইন +Comment[bs]=Dodatak za udaljeno kodiranje za Konqueror +Comment[ca]=Endollable de codificació remota per a Konqueror +Comment[cs]=Modul vzdáleného kódování pro Konqueror +Comment[csb]=Plugins daleczégò kòdowaniô dlô Konquerora +Comment[da]=Plugin for fjernkodning i Konqueror +Comment[de]=Modul zum Einstellen der Kodierung einer entfernten Gegenstelle +Comment[el]=Πρόσθετο απομακρυσμένης κωδικοποίησης για τον Konqueror +Comment[eo]=Fora kodoprezento Kromaĵo por Konkeranto +Comment[es]=Complemento de codificación remota para Konqueror +Comment[et]=Konquerori võrgukodeeringu plugin +Comment[eu]=Konquerorren urruneko kodeketa plugina +Comment[fa]=وصلۀ کدبندی دور برای Konqueror +Comment[fi]=Etämerkinmuunnosliitännäinen Konquerorille +Comment[fr]=Module d'encodage distant pour Konqueror +Comment[fy]=Eksterne-kodearringsplugin foar Konqueror +Comment[gl]=Plugin de codificación remota para Konqueror +Comment[he]=תוסף קידוד מרוחק עבור Konqueror +Comment[hr]=Dodatak za udaljeno kodiranje namijenjen Konqueroru +Comment[hu]=Távoli kódolás bővítőmodul a Konqueror böngészőhöz +Comment[is]=Fjarlægt kóðunaríforrit fyrir Konqueror +Comment[it]=Plugin per la codifica remota di Konqueror +Comment[ja]=Konqueror 用のリモートエンコーディングプラグイン +Comment[ka]=კოდირების დაშორებული მოდული Konqueror-ისთვის +Comment[kk]=Қашықтан баптау модулі +Comment[km]=កម្មវិធីជំនួយការអ៊ិនកូដសម្រាប់ Konqueror +Comment[ko]=Konqueror 원격 인코딩 플러그인 +Comment[lt]=Nutolusių vietų koduotės Konqueror priedas +Comment[mk]=Приклучок за оддалечено кодирање за Konqueror +Comment[ms]=Plugin Pengekodan Jauh untuk Konqueror +Comment[nb]=Eksterne kodingsprogramtillegg for Konqueror +Comment[nds]=Konqueror-Plugin för feern Koderen +Comment[ne]=कन्क्वेररका लागि टाढा सङ्केतन प्लगइन +Comment[nl]=Externe-coderingsplugin voor Konqueror +Comment[nn]=Eksterne kodingsprogramtillegg for Konqueror +Comment[pa]=ਕੋਨਕਿਉਰੋਰ ਲਈ ਰਿਮੋਟ ਇੰਕੋਡਿੰਗ ਪਲੱਗਇਨ +Comment[pl]=Wtyczka zdalnego kodowania dla Konquerora +Comment[pt]=Um 'Plugin' de Codificação Remota para o Konqueror +Comment[pt_BR]=Plug-in de Codificação Remota para o Konqueror +Comment[ro]=Plugin de încodare la distanță pentru Konqueror +Comment[ru]=Выбор кодировки для файлов на сервере +Comment[rw]=Icomeka Gusobeka rya Kure rijyanye na Konqueror +Comment[sk]=Modul pre šifrovanie pre Konqueror +Comment[sl]=Vstavek Oddaljeno kodiranje za Konqueror +Comment[sr]=Прикључак за удаљено кодирање за Konqueror +Comment[sr@Latn]=Priključak za udaljeno kodiranje za Konqueror +Comment[sv]=Insticksprogram för fjärrkodning i Konqueror +Comment[ta]=கான்கொரர்க்கான தொலைதூர குறியீட்டு சொருகுப்பொருள் +Comment[th]=ปลั้กอินเข้ารหัสทางไกลสำหรับคอนเควอร์เรอร์ +Comment[tr]=Konqueror için uzaktan şifreleme eklentisi +Comment[tt]=Konqueror öçen Remote Encoding Plugin +Comment[uk]=Втулок віддаленого кодування для Konqueror +Comment[vi]=Trình bổ sung Mã hoá Trên mạng cho Konqueror +Comment[wa]=Tchôke-divins d' ecôdaedje å lon po Konqueror +Comment[zh_CN]=Konqueror 的远程编码插件 +Comment[zh_TW]=Konqueror 的編碼外掛程式 diff --git a/konqueror/remoteencodingplugin/kremoteencodingplugin.h b/konqueror/remoteencodingplugin/kremoteencodingplugin.h new file mode 100644 index 000000000..85c77efa3 --- /dev/null +++ b/konqueror/remoteencodingplugin/kremoteencodingplugin.h @@ -0,0 +1,63 @@ +/* + Copyright (c) 2003 Thiago Macieira <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License (LGPL) 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 REMOTEENCODING_PLUGIN_H +#define REMOTEENCODING_PLUGIN_H + +#include <qstringlist.h> +#include <kurl.h> +#include <klibloader.h> +#include <kparts/plugin.h> + +class KActionMenu; +class KConfig; +class KonqDirPart; + +class KRemoteEncodingPlugin: public KParts::Plugin +{ + Q_OBJECT +public: + KRemoteEncodingPlugin(QObject * parent, const char *name, + const QStringList &); + ~KRemoteEncodingPlugin(); + +protected slots: + void slotAboutToOpenURL(); + void slotAboutToShow(); + void slotItemSelected(int); + void slotReload(); + void slotDefault(); + +private: + void updateBrowser(); + void loadSettings(); + void fillMenu(); + void updateMenu(); + + KonqDirPart *m_part; + KActionMenu *m_menu; + QStringList m_encodingDescriptions; + KURL m_currentURL; + + bool m_loaded; + int m_idDefault; +}; + +#endif diff --git a/konqueror/remoteencodingplugin/kremoteencodingplugin.rc b/konqueror/remoteencodingplugin/kremoteencodingplugin.rc new file mode 100644 index 000000000..29a283b4a --- /dev/null +++ b/konqueror/remoteencodingplugin/kremoteencodingplugin.rc @@ -0,0 +1,8 @@ +<!DOCTYPE kpartplugin> +<kpartplugin library="konq_remoteencoding"> +<MenuBar> + <Menu name="tools"><text>&Tools</text> + <Action name="changeremoteencoding"/> + </Menu> +</MenuBar> +</kpartplugin> diff --git a/konqueror/shellcmdplugin/Makefile.am b/konqueror/shellcmdplugin/Makefile.am new file mode 100644 index 000000000..cc213a53b --- /dev/null +++ b/konqueror/shellcmdplugin/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES= -I$(top_srcdir)/libkonq $(all_includes) +METASOURCES=AUTO + +kde_module_LTLIBRARIES = konq_shellcmdplugin.la +konq_shellcmdplugin_la_SOURCES = kshellcmdexecutor.cpp kshellcmddialog.cpp \ + kshellcmdplugin.cpp +konq_shellcmdplugin_la_LIBADD = $(top_builddir)/libkonq/libkonq.la +konq_shellcmdplugin_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) + +iconviewdir = $(kde_datadir)/konqiconview/kpartplugins +iconview_DATA = kshellcmdplugin.rc kshellcmdplugin.desktop + +listviewdir = $(kde_datadir)/konqlistview/kpartplugins +listview_DATA = kshellcmdplugin.rc kshellcmdplugin.desktop diff --git a/konqueror/shellcmdplugin/kshellcmddialog.cpp b/konqueror/shellcmdplugin/kshellcmddialog.cpp new file mode 100644 index 000000000..b39e35cd3 --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmddialog.cpp @@ -0,0 +1,90 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Alexander Neundorf <[email protected]> + + 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 <qhbox.h> +#include <qlayout.h> +#include <qlabel.h> + +#include <klocale.h> +#include <kstdguiitem.h> +#include <kpushbutton.h> + +#include "kshellcmddialog.h" +#include "kshellcmdexecutor.h" + +KShellCommandDialog::KShellCommandDialog(const QString& title, const QString& command, QWidget* parent, bool modal) + :KDialog(parent,"p",modal) +{ + QVBoxLayout * box=new QVBoxLayout (this,marginHint(),spacingHint()); + + QLabel *label=new QLabel(title,this); + m_shell=new KShellCommandExecutor(command,this); + + QHBox *buttonsBox=new QHBox(this); + buttonsBox->setSpacing(spacingHint()); + + cancelButton= new KPushButton(KStdGuiItem::cancel(), buttonsBox); + closeButton= new KPushButton(KStdGuiItem::close(), buttonsBox); + closeButton->setDefault(true); + + label->resize(label->sizeHint()); + m_shell->resize(m_shell->sizeHint()); + closeButton->setFixedSize(closeButton->sizeHint()); + cancelButton->setFixedSize(cancelButton->sizeHint()); + + box->addWidget(label,0); + box->addWidget(m_shell,1); + box->addWidget(buttonsBox,0); + + m_shell->setFocus(); + + connect(cancelButton, SIGNAL(clicked()), m_shell, SLOT(slotFinished())); + connect(m_shell, SIGNAL(finished()), this, SLOT(disableStopButton())); + connect(closeButton,SIGNAL(clicked()), this, SLOT(slotClose())); +} + +KShellCommandDialog::~KShellCommandDialog() +{ + delete m_shell; + m_shell=0; +} + +void KShellCommandDialog::disableStopButton() +{ + cancelButton->setEnabled(false); +} + +void KShellCommandDialog::slotClose() +{ + delete m_shell; + m_shell=0; + accept(); +} + +//blocking +int KShellCommandDialog::executeCommand() +{ + if (m_shell==0) + return 0; + //kdDebug()<<"---------- KShellCommandDialog::executeCommand()"<<endl; + m_shell->exec(); + return exec(); +} + +#include "kshellcmddialog.moc" diff --git a/konqueror/shellcmdplugin/kshellcmddialog.h b/konqueror/shellcmdplugin/kshellcmddialog.h new file mode 100644 index 000000000..790c8e0d0 --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmddialog.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Alexander Neundorf <[email protected]> + + 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 SHELLCOMMANDDIALOG_H +#define SHELLCOMMANDDIALOG_H + +#include <qstring.h> + +#include <kpushbutton.h> +#include <kdialog.h> +class QPushButton; +class KShellCommandExecutor; + +class KShellCommandDialog:public KDialog +{ + Q_OBJECT + public: + KShellCommandDialog(const QString& title, const QString& command, QWidget* parent=0, bool modal=false); + virtual ~KShellCommandDialog(); + //blocking + int executeCommand(); + protected: + + KShellCommandExecutor *m_shell; + KPushButton *cancelButton; + KPushButton *closeButton; + protected slots: + void disableStopButton(); + void slotClose(); +}; + +#endif diff --git a/konqueror/shellcmdplugin/kshellcmdexecutor.cpp b/konqueror/shellcmdplugin/kshellcmdexecutor.cpp new file mode 100644 index 000000000..c83488005 --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmdexecutor.cpp @@ -0,0 +1,156 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Alexander Neundorf <[email protected]> + + 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 "kshellcmdexecutor.h" + +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> +#include <stdlib.h> + +#include <qsocketnotifier.h> + +#include <kinputdialog.h> +#include <kglobalsettings.h> +#include <kdesu/process.h> +#include <klocale.h> + +KShellCommandExecutor::KShellCommandExecutor(const QString& command, QWidget* parent) +:QTextView(parent) +,m_shellProcess(0) +,m_command(command) +,m_readNotifier(0) +,m_writeNotifier(0) +{ + setTextFormat(PlainText); + setFont( KGlobalSettings::fixedFont() ); +} + +KShellCommandExecutor::~KShellCommandExecutor() +{ + if (m_shellProcess!=0) + { + ::kill(m_shellProcess->pid()+1, SIGTERM); + delete m_shellProcess; + }; +} + +int KShellCommandExecutor::exec() +{ + //kdDebug()<<"---------- KShellCommandExecutor::exec()"<<endl; + setText(""); + if (m_shellProcess!=0) + { + ::kill(m_shellProcess->pid(),SIGTERM); + delete m_shellProcess; + }; + if (m_readNotifier!=0) + delete m_readNotifier; + if (m_writeNotifier!=0) + delete m_writeNotifier; + + m_shellProcess=new PtyProcess(); + m_shellProcess->setTerminal(true); + + QCStringList args; + args+="-c"; + args+=m_command.local8Bit(); + //kdDebug()<<"------- executing: "<<m_command.local8Bit()<<endl; + + QCString shell( getenv("SHELL") ); + if (shell.isEmpty()) + shell = "sh"; + + int ret = m_shellProcess->exec(shell, args); + if (ret < 0) + { + //kdDebug()<<"could not execute"<<endl; + return 0; + } + + m_readNotifier=new QSocketNotifier(m_shellProcess->fd(),QSocketNotifier::Read, this); + m_writeNotifier=new QSocketNotifier(m_shellProcess->fd(),QSocketNotifier::Write, this); + m_writeNotifier->setEnabled(false); + connect (m_readNotifier, SIGNAL(activated(int)), this,SLOT(readDataFromShell())); + connect (m_writeNotifier, SIGNAL(activated(int)), this,SLOT(writeDataToShell())); + + return 1; +} + +void KShellCommandExecutor::readDataFromShell() +{ + //kdDebug()<<"--------- reading ------------"<<endl; + char buffer[16*1024]; + int bytesRead=::read(m_shellProcess->fd(), buffer, 16*1024-1); + //0-terminate the buffer + //process exited + if (bytesRead<=0) + { + slotFinished(); + } + else if (bytesRead>0) + { + //kdDebug()<<"***********************\n"<<buffer<<"###################\n"<<endl; + buffer[bytesRead]='\0'; + this->append(QString::fromLocal8Bit(buffer)); + setTextFormat(PlainText); + }; +} + +void KShellCommandExecutor::writeDataToShell() +{ + //kdDebug()<<"--------- writing ------------"<<endl; + bool ok; + QString str = KInputDialog::getText( QString::null, + i18n( "Input Required:" ), QString::null, &ok, this ); + if ( ok ) + { + QCString input=str.local8Bit(); + ::write(m_shellProcess->fd(),input,input.length()); + ::write(m_shellProcess->fd(),"\n",1); + } + else + slotFinished(); + + if (m_writeNotifier) + { + m_writeNotifier->setEnabled(false); + } +} + +void KShellCommandExecutor::slotFinished() +{ + setTextFormat(PlainText); + if (m_shellProcess!=0) + { + delete m_readNotifier; + m_readNotifier = 0; + delete m_writeNotifier; + m_writeNotifier = 0; + + //kdDebug()<<"slotFinished: pid: "<<m_shellProcess->pid()<<endl; + ::kill(m_shellProcess->pid()+1, SIGTERM); + ::kill(m_shellProcess->pid(), SIGTERM); + }; + delete m_shellProcess; + m_shellProcess=0; + emit finished(); +} + +#include "kshellcmdexecutor.moc" diff --git a/konqueror/shellcmdplugin/kshellcmdexecutor.h b/konqueror/shellcmdplugin/kshellcmdexecutor.h new file mode 100644 index 000000000..66b066a85 --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmdexecutor.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Alexander Neundorf <[email protected]> + + 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 SHELLCOMMANDEXECUTOR_H +#define SHELLCOMMANDEXECUTOR_H + +#include <qstring.h> +#include <qtextview.h> + +class PtyProcess; +class QSocketNotifier; + +class KShellCommandExecutor:public QTextView +{ + Q_OBJECT + public: + KShellCommandExecutor(const QString& command, QWidget* parent=0); + virtual ~KShellCommandExecutor(); + int exec(); + signals: + void finished(); + public slots: + void slotFinished(); + protected: + PtyProcess *m_shellProcess; + QString m_command; + QSocketNotifier *m_readNotifier; + QSocketNotifier *m_writeNotifier; + protected slots: + void readDataFromShell(); + void writeDataToShell(); +}; + +#endif diff --git a/konqueror/shellcmdplugin/kshellcmdplugin.cpp b/konqueror/shellcmdplugin/kshellcmdplugin.cpp new file mode 100644 index 000000000..b7f07ec81 --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmdplugin.cpp @@ -0,0 +1,90 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kshellcmdplugin.h" +#include <kinputdialog.h> +#include <kmessagebox.h> +#include <konq_dirpart.h> +#include <kprocess.h> +#include <kapplication.h> +#include "kshellcmddialog.h" +#include <kgenericfactory.h> +#include <kio/netaccess.h> + +KShellCmdPlugin::KShellCmdPlugin( QObject* parent, const char* name, + const QStringList & ) + : KParts::Plugin( parent, name ) +{ + if (!kapp->authorize("shell_access")) + return; + + new KAction( i18n( "&Execute Shell Command..." ), "run", CTRL+Key_E, this, + SLOT( slotExecuteShellCommand() ), actionCollection(), "executeshellcommand" ); +} + +void KShellCmdPlugin::slotExecuteShellCommand() +{ + KonqDirPart * part = dynamic_cast<KonqDirPart *>(parent()); + if ( !part ) + { + KMessageBox::sorry(0L, "KShellCmdPlugin::slotExecuteShellCommand: Program error, please report a bug."); + return; + } + KURL url = KIO::NetAccess::mostLocalURL(part->url(),NULL); + if ( !url.isLocalFile() ) + { + KMessageBox::sorry(part->widget(),i18n("Executing shell commands works only on local directories.")); + return; + } + QString path; + if ( part->currentItem() ) + { + // Putting the complete path to the selected file isn't really necessary, + // since we'll cd to the directory first. But we do need to get the + // complete relative path. + path = KURL::relativePath( url.path(), + part->currentItem()->url().path() ); + } + else + { + path = url.path(); + } + bool ok; + QString cmd = KInputDialog::getText( i18n("Execute Shell Command"), + i18n( "Execute shell command in current directory:" ), + KProcess::quote( path ), &ok, part->widget() ); + if ( ok ) + { + QString chDir; + chDir="cd "; + chDir+=KProcess::quote(part->url().path()); + chDir+="; "; + chDir+=cmd; + + KShellCommandDialog *shellCmdDialog=new KShellCommandDialog(i18n("Output from command: \"%1\"").arg(cmd),chDir,part->widget(),true); + shellCmdDialog->resize(500,300); + shellCmdDialog->executeCommand(); + delete shellCmdDialog; + } +} + +typedef KGenericFactory<KShellCmdPlugin> KonqShellCmdPluginFactory; +K_EXPORT_COMPONENT_FACTORY( konq_shellcmdplugin, KonqShellCmdPluginFactory( "kshellcmdplugin" ) ) + +#include "kshellcmdplugin.moc" + diff --git a/konqueror/shellcmdplugin/kshellcmdplugin.desktop b/konqueror/shellcmdplugin/kshellcmdplugin.desktop new file mode 100644 index 000000000..f5c1b3865 --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmdplugin.desktop @@ -0,0 +1,135 @@ +[Desktop Entry] +Type=Service +X-KDE-PluginInfo-Author=Alexander Neundorf +X-KDE-PluginInfo-Name=kshellcmdplugin +X-KDE-PluginInfo-Version=3.4 +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category=Tools +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-ParentApp=konqueror +Icon=run +Name=Shell Command Plugin +Name[af]=Opdrag tolk inprop module +Name[ar]=قابس أمر المحارة +Name[be]=Утулка выканання каманды ў абалонцы +Name[bg]=Изпълнение на команда +Name[bn]=শেল কমান্ড প্লাগ-ইন +Name[bs]=Dodatak za shell naredbe +Name[ca]=Endollable d'ordres +Name[cs]=Modul shellového příkazu +Name[csb]=Plugins pòlétu pòwłoczi +Name[da]=Plugin for skalkommando +Name[de]=Shell-Befehl-Plugin +Name[el]=Πρόσθετο εντολών κελύφους +Name[eo]=Ŝelkomanda kromaĵo +Name[es]=Complemento para ejecutar órdenes +Name[et]=Shellikäsu plugin +Name[eu]=Shell komandorako plugina +Name[fa]=وصلۀ فرمان پوسته +Name[fi]=Komentoriviliitännäinen +Name[fr]=Module de lignes de commande +Name[fy]=Flueslkommando-plugin +Name[gl]=Plugin para Execución de Comandos +Name[he]=תוסף הפעלת פקודה מסוף +Name[hr]=Dodatak za naredbe u ljuski +Name[hu]=Parancsvégrehajtó modul +Name[is]=Skeljarskipunar íforrit +Name[it]=Plugin per i comandi shell +Name[ja]=シェルコマンドプラグイン +Name[ka]=გარსისს ბრძანების მოდული +Name[kk]=Команда жолы +Name[km]=កម្មវិធីជំនួយពាក្យបញ្ជាសែល +Name[ko]=셸 명령 플러그인 +Name[lt]=Apvalkalo komandų priedas +Name[mk]=Приклучок за команда за школка +Name[ms]=Plugin Arahan Shell +Name[nb]=Programtillegg for skallkommandoer +Name[nds]=Plugin för Konsoolbefehlen +Name[ne]=शेल आदेश प्लगइन +Name[nl]=Schellcommando-plugin +Name[nn]=Programtillegg for skalkommandoar +Name[pa]=ਸੈੱਲ ਕਮਾਂਡ ਪਲੱਗਇਨ +Name[pl]=Wtyczka polecenia powłoki +Name[pt]='Plugin' para Executar um Comando +Name[pt_BR]=Plug-in do Shell +Name[ro]=Plugin shell pentru comenzi +Name[ru]=Выполнить команду +Name[rw]=Icomeka ry'Ibwirizwa Sheli +Name[sk]=Modul Príkaz shellu +Name[sl]=Vstavek Lupinski ukaz +Name[sr]=Прикључак за наредбе шкољке +Name[sr@Latn]=Priključak za naredbe školjke +Name[sv]=Insticksprogram för skalkommando +Name[ta]=ஓட்டு கட்டளை சொருகுப்பொருள் +Name[th]=ปลั๊กอินสำหรับป้อนคำสั่งเชลล์ +Name[tr]=Üçbirim Komut Eklentisi +Name[tt]=Qabıqqa Boyırıq birü Östämäse +Name[uk]=Втулок командної оболонки +Name[vi]=Trình bổ sung Ra lệnh qua Trình giao diện +Name[wa]=Tchôke-divins di comande shell +Name[zh_CN]=Shell 命令插件 +Name[zh_TW]=Shell 命令外掛程式 +Comment=Shell Command Plugin for Konqueror +Comment[af]=Opdrag tolk inprop module vir Konqueror +Comment[ar]=قابس أمر المحارة لِــ Konqueror +Comment[be]=Утулка выканання каманды ў абалонцы для Konqueror +Comment[bg]=Приставка за изпълнение на команда на браузъра +Comment[bn]=কনকরার-এর জন্য শেল কমান্ড প্লাগ-ইন +Comment[bs]=Dodatak za shell naredbe za Konqueror +Comment[ca]=Endollable d'ordres per a Konqueror +Comment[cs]=Modul shellového příkazu pro Konqueror +Comment[csb]=Plugins pòlétu pòwłoczi dlô Konquerora +Comment[da]=Plugin for skalkommandon i Konqueror +Comment[de]=Ein Shell-Befehl-Plugin für Konqueror +Comment[el]=Πρόσθετο εντολών κελύφους για τον Konqueror +Comment[eo]=Ŝelo Komando Kromaĵo por Konkeranto +Comment[es]=Complemento para ejecutar órdenes desde Konqueror +Comment[et]=Konquerori shellikäsu plugin +Comment[eu]=Shell komandorako plugina Konquerorako +Comment[fa]=وصلۀ فرمان پوسته برای Konqueror +Comment[fi]=Konquerorin komentoriviliitännäinen +Comment[fr]=Module de lignes de commande pour Konqueror +Comment[fy]=In flueskommando-plugin foar Konqueror +Comment[gl]=Plugin para Execución de Comandos para Konqueror +Comment[he]=תוסף הפעלת פקודה מסוף עבור Konqueror +Comment[hr]=Dodatak za naredbe u ljuski namijenjen Konqueroru +Comment[hu]=Parancsvégrehajtó modul a Konqueror böngészőhöz +Comment[is]=Skeljarskipunar íforrit fyrir Konqueror +Comment[it]=Plugin per i comandi shell di Konqueror +Comment[ja]=Konqueror 用シェルコマンドプラグイン +Comment[ka]=გარსისს ბრძანების მოდული Konqueror-ისთვის +Comment[kk]=Команда жолы модулі +Comment[km]=កម្មវិធីជំនួយពាក្យបញ្ជាសែលសម្រាប់ Konqueror +Comment[ko]=Konqueror 셸 명령 플러그인 +Comment[lt]=Apvalkalo komandų priedas Konqueror +Comment[mk]=Приклучок за команда за школка за Konqueror +Comment[ms]=Plugin Arahan Shell untuk Konqueror +Comment[nb]=Programtillegg for skallkommandoer i Konqueror +Comment[nds]=Konsoolbefehl-Plugin för Konqueror +Comment[ne]=कन्क्वेररका लागि शेल आदेश प्लगइन +Comment[nl]=Een shellcommando-plugin voor Konqueror +Comment[nn]=Programtillegg for skalkommandoar i Konqueror +Comment[pa]=ਕੋਨਕਿਉਰੋਰ ਲਈ ਸ਼ੈਲ ਕਮਾਂਡ ਪਲੱਗਇਨ +Comment[pl]=Wtyczka polecenia powłoki dla Konquerora +Comment[pt]=Um 'Plugin' para Executar Comandos no Konqueror +Comment[pt_BR]=Plug-in de Comandos do Shell para o Konqueror +Comment[ro]=Plugin shell pentru comenzi pentru Konqueror +Comment[ru]=Выполнить команду из Konqueror +Comment[rw]=Icomeka ry'Ibwiriza Sheli rijyanye na Konqueror +Comment[sk]=Modul Príkaz pre Konqueror +Comment[sl]=Vstavek Lupinski ukaz za Konqueror +Comment[sr]=Прикључак за наредбе шкољке за Konqueror +Comment[sr@Latn]=Priključak za naredbe školjke za Konqueror +Comment[sv]=Insticksprogram för skalkommandon i Konqueror +Comment[ta]=கான்கொரர்க்கான ஓட்டு கட்டளை சொருகுப்பொருள் +Comment[th]=ปลั้กอินป้อนคำสั่งเชลล์สำหรับของคอนเควอร์เรอร์ +Comment[tr]=Konqueror için uçbirim komut eklentisi +Comment[tt]=Konqueror öçen Qabıqqa Boyırıq birü Östämäse +Comment[uk]=Втулок командної оболонки для Konqueror +Comment[vi]=Trình bổ sung Ra lệnh qua Trình giao diện cho Konqueror +Comment[wa]=Tchôke-divins di comande shell po Konqueror +Comment[zh_CN]=Konqueror 的 Shell 命令插件 +Comment[zh_TW]=Konqueror 的 Shell 指令外掛程式 diff --git a/konqueror/shellcmdplugin/kshellcmdplugin.h b/konqueror/shellcmdplugin/kshellcmdplugin.h new file mode 100644 index 000000000..3e1415803 --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmdplugin.h @@ -0,0 +1,36 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef kshellcmdplugin_h +#define kshellcmdplugin_h + +#include <kparts/plugin.h> +#include <klibloader.h> + +class KShellCmdPlugin : public KParts::Plugin +{ + Q_OBJECT +public: + KShellCmdPlugin( QObject* parent, const char* name, const QStringList & ); + ~KShellCmdPlugin() {} + +public slots: + void slotExecuteShellCommand(); +}; + +#endif diff --git a/konqueror/shellcmdplugin/kshellcmdplugin.rc b/konqueror/shellcmdplugin/kshellcmdplugin.rc new file mode 100644 index 000000000..fab09c43f --- /dev/null +++ b/konqueror/shellcmdplugin/kshellcmdplugin.rc @@ -0,0 +1,8 @@ +<!DOCTYPE kpartplugin> +<kpartplugin name="kshellcmdplugin" library="konq_shellcmdplugin"> +<MenuBar> + <Menu name="tools"><text>&Tools</text> + <Action name="executeshellcommand"/> + </Menu> +</MenuBar> +</kpartplugin> diff --git a/konqueror/sidebar/.version b/konqueror/sidebar/.version new file mode 100644 index 000000000..9cb17c334 --- /dev/null +++ b/konqueror/sidebar/.version @@ -0,0 +1 @@ +Version=3 diff --git a/konqueror/sidebar/Makefile.am b/konqueror/sidebar/Makefile.am new file mode 100644 index 000000000..702320841 --- /dev/null +++ b/konqueror/sidebar/Makefile.am @@ -0,0 +1,44 @@ +# this has all of the subdirectories that make will recurse into. if +# there are none, comment this out +#SUBDIRS = . sidebar_classic trees + +#SUBDIRS = . +SUBDIRS = . trees web_module + +# set the include path for X, qt and KDE +INCLUDES = -I$(top_srcdir)/libkonq -I$(top_srcdir)/kate/lib $(all_includes) + +# these are the headers for your project +noinst_HEADERS = konqsidebar.h sidebar_widget.h konqsidebariface_p.h + +include_HEADERS = konqsidebarplugin.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +lib_LTLIBRARIES = libkonqsidebarplugin.la +kde_module_LTLIBRARIES = konq_sidebar.la + +# the Part's source, library search path, and link libraries +konq_sidebar_la_SOURCES = konqsidebar.cpp sidebar_widget.cpp +konq_sidebar_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +konq_sidebar_la_LIBADD = $(LIB_KPARTS) $(LIB_KIO) ../../libkonq/libkonq.la ./libkonqsidebarplugin.la $(LIB_KUTILS) + +libkonqsidebarplugin_la_SOURCES=konqsidebarplugin.cpp +libkonqsidebarplugin_la_LDFLAGS = -version-info 3:0:2 $(all_libraries) -no-undefined +libkonqsidebarplugin_la_LIBADD = $(LIB_KPARTS) + +# this is where the desktop file will go +partdesktopdir = $(kde_servicesdir) +partdesktop_DATA = konq_sidebartng.desktop + +# this is where the part's XML-GUI resource file goes +partrcdir = $(kde_confdir) +partrc_DATA = konqsidebartng.rc + +versiondir = $(kde_datadir)/konqsidebartng/entries/ +version_DATA=.version + +updatedir = $(kde_datadir)/kconf_update +update_DATA = konqsidebartng.upd +update_SCRIPTS = move_konqsidebartng_entries.sh diff --git a/konqueror/sidebar/konq_sidebartng.desktop b/konqueror/sidebar/konq_sidebartng.desktop new file mode 100644 index 000000000..b5842da7f --- /dev/null +++ b/konqueror/sidebar/konq_sidebartng.desktop @@ -0,0 +1,93 @@ +[Desktop Entry] +Type=Service +Icon=view_sidetree +Name=Navigation Panel +Name[af]=Navigasie Paneel +Name[ar]=لوحة الملاحة +Name[az]=Naviqasiya Paneli +Name[be]=Панэль навігацыі +Name[bg]=Навигационен панел +Name[bn]=ভ্রমণ প্যানেল +Name[br]=Panell furchal +Name[bs]=Panel za navigaciju +Name[ca]=Plafó de navegació +Name[cs]=Navigační panel +Name[csb]=Nawigacëjny panel +Name[cy]=Panel Llywio +Name[da]=Navigationspanel +Name[de]=Navigationsbereich +Name[el]=Πλαίσιο πλοήγησης +Name[eo]=Navigila panelo +Name[es]=Panel de navegación +Name[et]=Liikumise paneel +Name[eu]=Arakaketa panela +Name[fa]=تابلوی ناوش +Name[fi]=Navigointipaneeli +Name[fr]=Panneau de navigation +Name[fy]=Navigaasjepaniel +Name[ga]=Painéal Loingseoireachta +Name[gl]=Painel de Navegación +Name[he]=לוח ניווט +Name[hi]=नेविगेशन फलक +Name[hr]=Navigacijska ploča +Name[hu]=Navigációs panel +Name[is]=Leiðarstýrispjald +Name[it]=Pannello di navigazione +Name[ja]=ナビゲーションパネル +Name[ka]=სანავიგაციო პანელი +Name[kk]=Шарлау панелі +Name[km]=បន្ទះការរុករក +Name[ko]=탐색 패널 +Name[lo]=ຖາດນຳທາງ +Name[lt]=Navigacijos pultas +Name[lv]=Navigācijas Panelis +Name[mk]=Навигациски панел +Name[mn]=Жолоодлогын самбар +Name[ms]=Panel Navigasi +Name[mt]=Pannell ta' navigazzjoni +Name[nb]=Navigasjonspanel +Name[nds]=Navigatschoonspaneel +Name[ne]=नेभिगेसन प्यानल +Name[nl]=Navigatiepaneel +Name[nn]=Navigasjonspanel +Name[nso]=Panel ya Navigation +Name[pa]=ਏਧਰ-ਓਧਰ ਪੈਨਲ +Name[pl]=Panel nawigacyjny +Name[pt]=Painel de Navegação +Name[pt_BR]=Painel de Navegação +Name[ro]=Panou de navigare +Name[ru]=Панель навигации +Name[rw]=Umwanya w'Ibuganya +Name[se]=Navigašuvdnapanela +Name[sk]=Navigačný panel +Name[sl]=Navigacijski pult +Name[sr]=Навигациони панел +Name[sr@Latn]=Navigacioni panel +Name[sv]=Navigeringspanel +Name[ta]=நாவிகேஷன் பலகம் +Name[tg]=Сафҳаи контроли ҷустуҷӯ +Name[th]=ถาดนำทาง +Name[tr]=Dolaşma Paneli +Name[tt]=Küçü Qoraltiräse +Name[uk]=Панель навігації +Name[uz]=Yoʻlchi paneli +Name[uz@cyrillic]=Йўлчи панели +Name[ven]=Phanele ya Navigation +Name[vi]=Bảng điều khiển Duyệt +Name[wa]=Panea d' naiviaedje +Name[xh]=Iqela lenjongo Yolawulo +Name[zh_CN]=导航面板 +Name[zh_TW]=導覽面板 +Name[zu]=Iwindi lemininingwane Lokuzula +MimeType=inode/directory +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=konq_sidebar +X-KDE-BrowserView-AllowAsDefault=false +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-PassiveMode=true +X-KDE-BrowserView-Toggable=true +X-KDE-BrowserView-ToggableView-Orientation=vertical +X-KDE-BrowserView-HierarchicalView=true +X-KDE-BrowserView-FollowActive=true +X-KDE-BrowserView-LinkedView=false +X-KDE-BrowserView-Built-Into=konqueror diff --git a/konqueror/sidebar/konqsidebar.cpp b/konqueror/sidebar/konqsidebar.cpp new file mode 100644 index 000000000..ae2880b13 --- /dev/null +++ b/konqueror/sidebar/konqsidebar.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + konqsidebar.cpp + ------------------- + begin : Sat June 2 16:25:27 CEST 2001 + copyright : (C) 2001 Joseph Wenninger + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "konqsidebar.h" +#include "konqsidebariface_p.h" + +#include <konq_events.h> +#include <kdebug.h> +#include <qapplication.h> +#include <kaccelmanager.h> + +KonqSidebar::KonqSidebar( QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, bool universalMode ) +: KParts::ReadOnlyPart(parent, name),KonqSidebarIface() +{ + // we need an instance + setInstance( KonqSidebarFactory::instance() ); + m_extension = 0; + // this should be your custom internal widget + m_widget = new Sidebar_Widget( parentWidget, this, widgetName ,universalMode, parentWidget->topLevelWidget()->property("currentProfile").toString() ); + m_extension = new KonqSidebarBrowserExtension( this, m_widget,"KonqSidebar::BrowserExtension" ); + connect(m_widget,SIGNAL(started(KIO::Job *)), + this, SIGNAL(started(KIO::Job*))); + connect(m_widget,SIGNAL(completed()),this,SIGNAL(completed())); + connect(m_extension, SIGNAL(addWebSideBar(const KURL&, const QString&)), + m_widget, SLOT(addWebSideBar(const KURL&, const QString&))); + KAcceleratorManager::setNoAccel(m_widget); + setWidget(m_widget); +} + +KInstance *KonqSidebar::getInstance() +{ + kdDebug() << "KonqSidebar::getInstance()" << endl; + return KonqSidebarFactory::instance(); +} + +KonqSidebar::~KonqSidebar() +{ +} + +bool KonqSidebar::openFile() +{ + return true; +} + +bool KonqSidebar::openURL(const KURL &url) { + if (m_widget) + return m_widget->openURL(url); + else return false; +} + +void KonqSidebar::customEvent(QCustomEvent* ev) +{ + if (KonqFileSelectionEvent::test(ev) || + KonqFileMouseOverEvent::test(ev) || + KonqConfigEvent::test(ev)) + { + // Forward the event to the widget + QApplication::sendEvent( m_widget, ev ); + } +} + + + +// It's usually safe to leave the factory code alone.. with the +// notable exception of the KAboutData data +#include <kaboutdata.h> +#include <klocale.h> +#include <kinstance.h> + +KInstance* KonqSidebarFactory::s_instance = 0L; +KAboutData* KonqSidebarFactory::s_about = 0L; + +KonqSidebarFactory::KonqSidebarFactory() + : KParts::Factory() +{ +} + +KonqSidebarFactory::~KonqSidebarFactory() +{ + delete s_instance; + s_instance = 0L; + delete s_about; + s_about = 0L; +} + +KParts::Part* KonqSidebarFactory::createPartObject( QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, + const char * /*classname*/, const QStringList &args ) +{ + // Create an instance of our Part + KonqSidebar* obj = new KonqSidebar( parentWidget, widgetName, parent, name, args.contains("universal") ); + + // See if we are to be read-write or not +// if (QCString(classname) == "KParts::ReadOnlyPart") + // obj->setReadWrite(false); + + return obj; +} + +KInstance* KonqSidebarFactory::instance() +{ + if( !s_instance ) + { + s_about = new KAboutData("konqsidebartng", I18N_NOOP("Extended Sidebar"), "0.1"); + s_about->addAuthor("Joseph WENNINGER", 0, "[email protected]"); + s_instance = new KInstance(s_about); + } + return s_instance; +} + +K_EXPORT_COMPONENT_FACTORY( konq_sidebar, KonqSidebarFactory ) + +#include "konqsidebar.moc" diff --git a/konqueror/sidebar/konqsidebar.h b/konqueror/sidebar/konqsidebar.h new file mode 100644 index 000000000..32a5f5679 --- /dev/null +++ b/konqueror/sidebar/konqsidebar.h @@ -0,0 +1,126 @@ +/*************************************************************************** + konqsidebar.h + ------------------- + begin : Sat June 2 16:25:27 CEST 2001 + copyright : (C) 2001 Joseph Wenninger + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef KONQSIDEBARPART_H +#define KONQSIDEBARPART_H + +#include <kparts/part.h> +#include <kparts/factory.h> +#include <kparts/event.h> +#include <kparts/browserextension.h> +#include <qguardedptr.h> +#include "sidebar_widget.h" +#include "konqsidebariface_p.h" + +class QWidget; +class QPainter; +class QCustomEvent; +class KURL; + + +class KonqSidebar; +class KonqSidebarFactory; + +class KonqSidebarBrowserExtension : public KParts::BrowserExtension +{ + Q_OBJECT + public: + KonqSidebarBrowserExtension(KonqSidebar *part_,Sidebar_Widget *widget_,const char *name): + KParts::BrowserExtension((KParts::ReadOnlyPart*)part_,name),widget(widget_){;} + ~KonqSidebarBrowserExtension(){;} + + protected: + QGuardedPtr<Sidebar_Widget> widget; + + +// The following slots are needed for konqueror's standard actions + protected slots: + void copy(){if (widget) widget->stdAction("copy()");} + void cut(){if (widget) widget->stdAction("cut()");} + void paste(){if (widget) widget->stdAction("paste()");} + void pasteTo(const KURL&){if (widget) widget->stdAction("paste()");} + void trash(){if (widget) widget->stdAction("trash()");} + void del(){if (widget) widget->stdAction("del()");} + void rename(){if (widget) widget->stdAction("rename()");} + void properties() {if (widget) widget->stdAction("properties()");} + void editMimeType() {if (widget) widget->stdAction("editMimeType()");} + // @li @p print : Print :-) not supported + void reparseConfiguration() {if (widget) widget->stdAction("reparseConfiguration()");} + void refreshMimeTypes () { if (widget) widget->stdAction("refreshMimeTypes()");} +}; + +/** + * This is a "Part". It that does all the real work in a KPart + * application. + * + * @short Main Part + * @author Joseph WENNINGER <[email protected]> + * @version 0.1 + */ +class KonqSidebar : public KParts::ReadOnlyPart, public KonqSidebarIface +{ + Q_OBJECT +public: + /** + * Default constructor + */ + KonqSidebar(QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name,bool universalMode); + + /** + * Destructor + */ + virtual ~KonqSidebar(); + + virtual bool openURL(const KURL &url); + KonqSidebarBrowserExtension* extension() const + { return m_extension; } + KInstance *getInstance(); + virtual bool universalMode() {return m_universalMode;} +protected: + /** + * This must be implemented by each part + */ + KonqSidebarBrowserExtension * m_extension; + virtual bool openFile(); + + virtual void customEvent(QCustomEvent* ev); + +private: + class Sidebar_Widget *m_widget; + bool m_universalMode; +}; + +class KInstance; +class KAboutData; + +class KonqSidebarFactory : public KParts::Factory +{ + Q_OBJECT +public: + KonqSidebarFactory(); + virtual ~KonqSidebarFactory(); + virtual KParts::Part* createPartObject( QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, + const char *classname, const QStringList &args ); + static KInstance* instance(); + +private: + static KInstance* s_instance; + static KAboutData* s_about; +}; + +#endif // KPARTAPPPART_H diff --git a/konqueror/sidebar/konqsidebariface_p.h b/konqueror/sidebar/konqsidebariface_p.h new file mode 100644 index 000000000..2a693d004 --- /dev/null +++ b/konqueror/sidebar/konqsidebariface_p.h @@ -0,0 +1,9 @@ +#ifndef _KONQSIDEBARIFACE_H_ +#define _KONQSIDEBARIFACE_H_ +class KonqSidebarIface { +public: + KonqSidebarIface(){} + virtual ~KonqSidebarIface(){} + virtual bool universalMode()=0; +}; +#endif diff --git a/konqueror/sidebar/konqsidebarplugin.cpp b/konqueror/sidebar/konqsidebarplugin.cpp new file mode 100644 index 000000000..b2b7d9f17 --- /dev/null +++ b/konqueror/sidebar/konqsidebarplugin.cpp @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2001,2002 Joseph Wenninger <[email protected]> + + 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 "konqsidebarplugin.moc" +#include "konqsidebariface_p.h" +#include <kdebug.h> + + +KonqSidebarPlugin::KonqSidebarPlugin(KInstance *instance,QObject *parent, + QWidget * /*widgetParent*/, QString &desktopName_, const char* name) + : QObject(parent,name), desktopName(desktopName_) +{ + m_parentInstance=instance; +} + +KonqSidebarPlugin::~KonqSidebarPlugin() { } + +KInstance *KonqSidebarPlugin::parentInstance(){return m_parentInstance;} + +void KonqSidebarPlugin::openURL(const KURL& url){handleURL(url);} + +void KonqSidebarPlugin::openPreview(const KFileItemList& items) +{ + handlePreview(items); +} + +void KonqSidebarPlugin::openPreviewOnMouseOver(const KFileItem& item) +{ + handlePreviewOnMouseOver(item); +} + +void KonqSidebarPlugin::handlePreview(const KFileItemList & /*items*/) {} + +void KonqSidebarPlugin::handlePreviewOnMouseOver(const KFileItem& /*items*/) {} + + +bool KonqSidebarPlugin::universalMode() { + if (!parent()) return false; + KonqSidebarIface *ksi=static_cast<KonqSidebarIface*>(parent()->qt_cast("KonqSidebarIface")); + if (!ksi) return false; + kdDebug()<<"calling KonqSidebarIface->universalMode()"<<endl; + return ksi->universalMode(); +} diff --git a/konqueror/sidebar/konqsidebarplugin.h b/konqueror/sidebar/konqsidebarplugin.h new file mode 100644 index 000000000..ad931070f --- /dev/null +++ b/konqueror/sidebar/konqsidebarplugin.h @@ -0,0 +1,97 @@ +/* This file is part of the KDE project + Copyright (C) 2001,2002 Joseph Wenninger <[email protected]> + + 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 _konqsidebarplugin_h_ +#define _konqsidebarplugin_h_ +#include <qwidget.h> +#include <qobject.h> +#include <kurl.h> +#include <qstring.h> +#include <kparts/part.h> +#include <kparts/browserextension.h> +#include <kio/job.h> +#include <qguardedptr.h> +#include <kfileitem.h> + +class KonqSidebarPluginPrivate; + +class KDE_EXPORT KonqSidebarPlugin : public QObject +{ + Q_OBJECT + public: + KonqSidebarPlugin(KInstance *instance,QObject *parent,QWidget *widgetParent,QString &desktopName_, const char* name=0); + ~KonqSidebarPlugin(); + virtual QWidget *getWidget()=0; + virtual void *provides(const QString &)=0; + KInstance *parentInstance(); + protected: + virtual void handleURL(const KURL &url)=0; + virtual void handlePreview(const KFileItemList & items); + virtual void handlePreviewOnMouseOver(const KFileItem &items); //not used yet, perhaps in KDE 3.1 + QString desktopName; + KInstance* m_parentInstance; + + private: + KonqSidebarPluginPrivate *d; + + signals: + void requestURL(KURL&); + void started(KIO::Job *); + void completed(); + void setIcon(const QString& icon); + void setCaption(const QString& caption); + + + protected: + bool universalMode(); + public slots: + void openURL(const KURL& url); + + void openPreview(const KFileItemList& items); + + void openPreviewOnMouseOver(const KFileItem& item); // not used yet, perhaps KDE 3.1 + /* + if your plugin supports a setup dialog, instead (replaces the url menu entry in the popup) (not supported yet) + void setup(QWidget *parent); + + */ + + + /* signals, which could be, but need not to be added + + void openURLRequest( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + void createNewWindow( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + + void enableAction( const char * name, bool enabled ); + + void popupMenu( const QPoint &global, const KFileItemList &items ); + void popupMenu( KXMLGUIClient *client, const QPoint &global, const KFileItemList &items ); + void popupMenu( const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode = (mode_t)-1 ); + void popupMenu( KXMLGUIClient *client, + const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode = (mode_t)-1 ); + + void showError(QString &); //for later extension + void showMessage(QString &); //for later extension + + */ + +}; + +#endif diff --git a/konqueror/sidebar/konqsidebartng.rc b/konqueror/sidebar/konqsidebartng.rc new file mode 100644 index 000000000..2d1ebb484 --- /dev/null +++ b/konqueror/sidebar/konqsidebartng.rc @@ -0,0 +1,7 @@ +[filemanagement] +OpenViews=home.desktop +SingleWidgetMode=true + +[webbrowsing] +OpenViews=bookmarks.desktop +SingleWidgetMode=true diff --git a/konqueror/sidebar/konqsidebartng.upd b/konqueror/sidebar/konqsidebartng.upd new file mode 100644 index 000000000..f71b688d8 --- /dev/null +++ b/konqueror/sidebar/konqsidebartng.upd @@ -0,0 +1,12 @@ +Id=konqsidebartng_rc +File=konqsidebartng.rc +Group=<default>,webbrowsing +Options=Copy +AllKeys +Group=<default>,filemanagement +Options=Copy +AllKeys +RemoveGroup=<default> + +Id=konqsidebartng_entries +Script=move_konqsidebartng_entries.sh,sh diff --git a/konqueror/sidebar/move_konqsidebartng_entries.sh b/konqueror/sidebar/move_konqsidebartng_entries.sh new file mode 100644 index 000000000..83de07bf3 --- /dev/null +++ b/konqueror/sidebar/move_konqsidebartng_entries.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +prefix=$(kde-config --localprefix) +source="$prefix/share/apps/konqsidebartng" + +[ -d "$source/entries" ] || exit 0 + +profiles="filemanagement webbrowsing" +for profile in $profiles; do + dest="$source/$profile/entries" + if [ ! -d "$dest" ]; then + mkdir -p "$dest" || exit 1 + cp $source/entries/.version $dest/ + cp $source/entries/* $dest/ + fi +done + +rm -rf $source/entries diff --git a/konqueror/sidebar/sidebar_widget.cpp b/konqueror/sidebar/sidebar_widget.cpp new file mode 100644 index 000000000..3b402b25e --- /dev/null +++ b/konqueror/sidebar/sidebar_widget.cpp @@ -0,0 +1,1310 @@ +/*************************************************************************** + sidebar_widget.cpp + ------------------- + begin : Sat June 2 16:25:27 CEST 2001 + copyright : (C) 2001 Joseph Wenninger + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include <config.h> + +#include <limits.h> + +#include <qdir.h> +#include <qpopupmenu.h> +#include <qhbox.h> +#include <qpushbutton.h> +#include <qwhatsthis.h> +#include <qlayout.h> +#include <qstringlist.h> + +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kicondialog.h> +#include <kmessagebox.h> +#include <kinputdialog.h> +#include <konq_events.h> +#include <kfileitem.h> +#include <kio/netaccess.h> +#include <kpopupmenu.h> +#include <kprocess.h> +#include <kurlrequesterdlg.h> +#include <kinputdialog.h> +#include <kfiledialog.h> +#include <kdesktopfile.h> +#include "konqsidebar.h" + +#include "sidebar_widget.h" +#include "sidebar_widget.moc" + + +addBackEnd::addBackEnd(QWidget *parent, class QPopupMenu *addmenu, + bool universal, const QString ¤tProfile, + const char *name) + : QObject(parent,name), + m_parent(parent) +{ + m_universal=universal; + m_currentProfile = currentProfile; + menu = addmenu; + connect(menu,SIGNAL(aboutToShow()),this,SLOT(aboutToShowAddMenu())); + connect(menu,SIGNAL(activated(int)),this,SLOT(activatedAddMenu(int))); +} + +void addBackEnd::aboutToShowAddMenu() +{ + if (!menu) + return; + KStandardDirs *dirs = KGlobal::dirs(); + QStringList list = dirs->findAllResources("data","konqsidebartng/add/*.desktop",true,true); + libNames.setAutoDelete(true); + libNames.resize(0); + libParam.setAutoDelete(true); + libParam.resize(0); + menu->clear(); + int i = 0; + + for (QStringList::Iterator it = list.begin(); it != list.end(); ++it, i++ ) + { + KDesktopFile *confFile; + + confFile = new KDesktopFile(*it, true); + if (! confFile->tryExec()) { + delete confFile; + i--; + continue; + } + if (m_universal) { + if (confFile->readEntry("X-KDE-KonqSidebarUniversal").upper()!="TRUE") { + delete confFile; + i--; + continue; + } + } else { + if (confFile->readEntry("X-KDE-KonqSidebarBrowser").upper()=="FALSE") { + delete confFile; + i--; + continue; + } + } + QString icon = confFile->readIcon(); + if (!icon.isEmpty()) + { + menu->insertItem(SmallIcon(icon), + confFile->readEntry("Name"), i); + } else { + menu->insertItem(confFile->readEntry("Name"), i); + } + libNames.resize(libNames.size()+1); + libNames.insert(libNames.count(), new QString(confFile->readEntry("X-KDE-KonqSidebarAddModule"))); + libParam.resize(libParam.size()+1); + libParam.insert(libParam.count(), new QString(confFile->readEntry("X-KDE-KonqSidebarAddParam"))); + delete confFile; + } + menu->insertSeparator(); + menu->insertItem(i18n("Rollback to System Default"), i); +} + + +void addBackEnd::doRollBack() +{ + if (KMessageBox::warningContinueCancel(m_parent, i18n("<qt>This removes all your entries from the sidebar and adds the system default ones.<BR><B>This procedure is irreversible</B><BR>Do you want to proceed?</qt>"))==KMessageBox::Continue) + { + KStandardDirs *dirs = KGlobal::dirs(); + QString loc=dirs->saveLocation("data","konqsidebartng/" + m_currentProfile + "/",true); + QDir dir(loc); + QStringList dirEntries = dir.entryList( QDir::Dirs | QDir::NoSymLinks ); + dirEntries.remove("."); + dirEntries.remove(".."); + for ( QStringList::Iterator it = dirEntries.begin(); it != dirEntries.end(); ++it ) { + if ((*it)!="add") + KIO::NetAccess::del(KURL( loc+(*it) ), m_parent); + } + emit initialCopyNeeded(); + } +} + + +static QString findFileName(const QString* tmpl,bool universal, const QString &profile) { + QString myFile, filename; + KStandardDirs *dirs = KGlobal::dirs(); + QString tmp = *tmpl; + + if (universal) { + dirs->saveLocation("data", "konqsidebartng/kicker_entries/", true); + tmp.prepend("/konqsidebartng/kicker_entries/"); + } else { + dirs->saveLocation("data", "konqsidebartng/" + profile + "/entries/", true); + tmp.prepend("/konqsidebartng/" + profile + "/entries/"); + } + filename = tmp.arg(""); + myFile = locateLocal("data", filename); + + if (QFile::exists(myFile)) { + for (ulong l = 0; l < ULONG_MAX; l++) { + filename = tmp.arg(l); + myFile = locateLocal("data", filename); + if (!QFile::exists(myFile)) { + break; + } else { + myFile = QString::null; + } + } + } + + return myFile; +} + +void addBackEnd::activatedAddMenu(int id) +{ + kdDebug() << "activatedAddMenu: " << QString("%1").arg(id) << endl; + if (((uint)id) == libNames.size()) + doRollBack(); + if(((uint)id) >= libNames.size()) + return; + + KLibLoader *loader = KLibLoader::self(); + + // try to load the library + QString libname = *libNames.at(id); + KLibrary *lib = loader->library(QFile::encodeName(libname)); + if (lib) + { + // get the create_ function + QString factory("add_"); + factory = factory+(*libNames.at(id)); + void *add = lib->symbol(QFile::encodeName(factory)); + + if (add) + { + //call the add function + bool (*func)(QString*, QString*, QMap<QString,QString> *); + QMap<QString,QString> map; + func = (bool (*)(QString*, QString*, QMap<QString,QString> *)) add; + QString *tmp = new QString(""); + if (func(tmp,libParam.at(id),&map)) + { + QString myFile = findFileName(tmp,m_universal,m_currentProfile); + + if (!myFile.isEmpty()) + { + kdDebug() <<"trying to save to file: "<<myFile << endl; + KSimpleConfig scf(myFile,false); + scf.setGroup("Desktop Entry"); + for (QMap<QString,QString>::ConstIterator it = map.begin(); it != map.end(); ++it) { + kdDebug() <<"writing:"<<it.key()<<" / "<<it.data()<<endl; + scf.writePathEntry(it.key(), it.data()); + } + scf.sync(); + emit updateNeeded(); + + } else { + kdWarning() << "No unique filename found" << endl; + } + } else { + kdWarning() << "No new entry (error?)" << endl; + } + delete tmp; + } + } else { + kdWarning() << "libname:" << libNames.at(id) + << " doesn't specify a library!" << endl; + } +} + + +/**************************************************************/ +/* Sidebar_Widget */ +/**************************************************************/ + +Sidebar_Widget::Sidebar_Widget(QWidget *parent, KParts::ReadOnlyPart *par, const char *name,bool universalMode, const QString ¤tProfile) + :QWidget(parent,name),m_universalMode(universalMode),m_partParent(par),m_currentProfile(currentProfile) +{ + m_somethingVisible = false; + m_initial = true; + m_noUpdate = false; + m_layout = 0; + m_currentButton = 0; + m_activeModule = 0; + m_userMovedSplitter = false; + //kdDebug() << "**** Sidebar_Widget:SidebarWidget()"<<endl; + if (universalMode) + { + m_relPath = "konqsidebartng/kicker_entries/"; + } + else + { + m_relPath = "konqsidebartng/" + currentProfile + "/entries/"; + } + m_path = KGlobal::dirs()->saveLocation("data", m_relPath, true); + m_buttons.setAutoDelete(true); + m_hasStoredUrl = false; + m_latestViewed = -1; + setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + + QSplitter *splitterWidget = splitter(); + if (splitterWidget) { + splitterWidget->setResizeMode(parent, QSplitter::FollowSizeHint); + splitterWidget->setOpaqueResize( false ); + connect(splitterWidget,SIGNAL(setRubberbandCalled()),SLOT(userMovedSplitter())); + } + + m_area = new KDockArea(this); + m_area->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + m_mainDockWidget = m_area->createDockWidget("free", 0); + m_mainDockWidget->setWidget(new QWidget(m_mainDockWidget)); + m_area->setMainDockWidget(m_mainDockWidget); + m_area->setMinimumWidth(0); + m_mainDockWidget->setDockSite(KDockWidget::DockTop); + m_mainDockWidget->setEnableDocking(KDockWidget::DockNone); + + m_buttonBar = new KMultiTabBar(KMultiTabBar::Vertical,this); + m_buttonBar->showActiveTabTexts(true); + + m_menu = new QPopupMenu(this, "Sidebar_Widget::Menu"); + QPopupMenu *addMenu = new QPopupMenu(this, "Sidebar_Widget::addPopup"); + m_menu->insertItem(i18n("Add New"), addMenu, 0); + m_menu->insertItem(i18n("Multiple Views"), 1); + m_menu->insertItem(i18n("Show Tabs Left"), 2); + m_menu->insertItem(i18n("Show Configuration Button"), 3); + if (!m_universalMode) { + m_menu->insertItem(SmallIconSet("remove"), + i18n("Close Navigation Panel"), + par, SLOT(deleteLater())); + } + connect(m_menu, SIGNAL(aboutToShow()), + this, SLOT(aboutToShowConfigMenu())); + connect(m_menu, SIGNAL(activated(int)), + this, SLOT(activatedMenu(int))); + + m_buttonPopup = 0; + addBackEnd *ab = new addBackEnd(this, addMenu, universalMode, + currentProfile, + "Sidebar_Widget-addBackEnd"); + + connect(ab, SIGNAL(updateNeeded()), + this, SLOT(updateButtons())); + connect(ab, SIGNAL(initialCopyNeeded()), + this, SLOT(finishRollBack())); + + initialCopy(); + + if (universalMode) + { + m_config = new KConfig("konqsidebartng_kicker.rc"); + } + else + { + m_config = new KConfig("konqsidebartng.rc"); + m_config->setGroup(currentProfile); + } + readConfig(); + + // Disable stuff (useful for Kiosk mode)! + m_menu->setItemVisible(1, !m_immutableSingleWidgetMode); + m_menu->setItemVisible(2, !m_immutableShowTabsLeft); + m_menu->setItemVisible(3, !m_immutableShowExtraButtons); + + connect(&m_configTimer, SIGNAL(timeout()), + this, SLOT(saveConfig())); + m_somethingVisible = !m_openViews.isEmpty(); + doLayout(); + QTimer::singleShot(0,this,SLOT(createButtons())); + connect(m_area, SIGNAL(dockWidgetHasUndocked(KDockWidget*)), + this, SLOT(dockWidgetHasUndocked(KDockWidget*))); +} + +void Sidebar_Widget::addWebSideBar(const KURL& url, const QString& /*name*/) { + //kdDebug() << "Web sidebar entry to be added: " << url.url() + // << " [" << name << "]" << endl; + + // Look for existing ones with this URL + KStandardDirs *dirs = KGlobal::dirs(); + QString list; + dirs->saveLocation("data", m_relPath, true); + list = locateLocal("data", m_relPath); + + // Go through list to see which ones exist. Check them for the URL + QStringList files = QDir(list).entryList("websidebarplugin*.desktop"); + for (QStringList::Iterator it = files.begin(); it != files.end(); ++it){ + KSimpleConfig scf(list + *it, false); + scf.setGroup("Desktop Entry"); + if (scf.readPathEntry("URL", QString::null) == url.url()) { + // We already have this one! + KMessageBox::information(this, + i18n("This entry already exists.")); + return; + } + } + + QString tmpl = "websidebarplugin%1.desktop"; + QString myFile = findFileName(&tmpl,m_universalMode,m_currentProfile); + + if (!myFile.isEmpty()) { + KSimpleConfig scf(myFile, false); + scf.setGroup("Desktop Entry"); + scf.writeEntry("Type", "Link"); + scf.writePathEntry("URL", url.url()); + scf.writeEntry("Icon", "netscape"); + scf.writeEntry("Name", i18n("Web SideBar Plugin")); + scf.writeEntry("Open", "true"); + scf.writeEntry("X-KDE-KonqSidebarModule", "konqsidebar_web"); + scf.sync(); + + QTimer::singleShot(0,this,SLOT(updateButtons())); + } +} + + +void Sidebar_Widget::finishRollBack() +{ + m_path = KGlobal::dirs()->saveLocation("data",m_relPath,true); + initialCopy(); + QTimer::singleShot(0,this,SLOT(updateButtons())); +} + + +void Sidebar_Widget::saveConfig() +{ + m_config->writeEntry("SingleWidgetMode",m_singleWidgetMode); + m_config->writeEntry("ShowExtraButtons",m_showExtraButtons); + m_config->writeEntry("ShowTabsLeft", m_showTabsLeft); + m_config->writeEntry("HideTabs", m_hideTabs); + m_config->writeEntry("SavedWidth",m_savedWidth); + m_config->sync(); +} + +void Sidebar_Widget::doLayout() +{ + if (m_layout) + delete m_layout; + + m_layout = new QHBoxLayout(this); + if (m_showTabsLeft) + { + m_layout->add(m_buttonBar); + m_layout->add(m_area); + m_buttonBar->setPosition(KMultiTabBar::Left); + } else { + m_layout->add(m_area); + m_layout->add(m_buttonBar); + m_buttonBar->setPosition(KMultiTabBar::Right); + } + m_layout->activate(); + if (m_hideTabs) m_buttonBar->hide(); + else m_buttonBar->show(); +} + + +void Sidebar_Widget::aboutToShowConfigMenu() +{ + m_menu->setItemChecked(1, !m_singleWidgetMode); + m_menu->setItemChecked(2, m_showTabsLeft); + m_menu->setItemChecked(3, m_showExtraButtons); +} + + +void Sidebar_Widget::initialCopy() +{ + kdDebug()<<"Initial copy"<<endl; + QStringList dirtree_dirs; + if (m_universalMode) + dirtree_dirs = KGlobal::dirs()->findDirs("data","konqsidebartng/kicker_entries/"); + else + dirtree_dirs = KGlobal::dirs()->findDirs("data","konqsidebartng/entries/"); + if (dirtree_dirs.last()==m_path) + return; //oups; + + int nVersion=-1; + KSimpleConfig lcfg(m_path+".version"); + int lVersion=lcfg.readNumEntry("Version",0); + + + for (QStringList::const_iterator ddit=dirtree_dirs.begin();ddit!=dirtree_dirs.end();++ddit) { + QString dirtree_dir=*ddit; + if (dirtree_dir == m_path) continue; + + + kdDebug()<<"************************************ retrieving directory info:"<<dirtree_dir<<endl; + + if ( !dirtree_dir.isEmpty() && dirtree_dir != m_path ) + { + KSimpleConfig gcfg(dirtree_dir+".version"); + int gversion = gcfg.readNumEntry("Version", 1); + nVersion=(nVersion>gversion)?nVersion:gversion; + if (lVersion >= gversion) + continue; + + QDir dir(m_path); + QStringList entries = dir.entryList( QDir::Files ); + QStringList dirEntries = dir.entryList( QDir::Dirs | QDir::NoSymLinks ); + dirEntries.remove( "." ); + dirEntries.remove( ".." ); + + QDir globalDir( dirtree_dir ); + Q_ASSERT( globalDir.isReadable() ); + // Only copy the entries that don't exist yet in the local dir + QStringList globalDirEntries = globalDir.entryList(); + QStringList::ConstIterator eIt = globalDirEntries.begin(); + QStringList::ConstIterator eEnd = globalDirEntries.end(); + for (; eIt != eEnd; ++eIt ) + { + //kdDebug(1201) << "KonqSidebarTree::scanDir dirtree_dir contains " << *eIt << endl; + if ( *eIt != "." && *eIt != ".." && + !entries.contains( *eIt ) && + !dirEntries.contains( *eIt ) ) + { // we don't have that one yet -> copy it. + QString cp("cp -R -- "); + cp += KProcess::quote(dirtree_dir + *eIt); + cp += " "; + cp += KProcess::quote(m_path); + kdDebug() << "SidebarWidget::intialCopy executing " << cp << endl; + ::system( QFile::encodeName(cp) ); + } + } + } + + lcfg.writeEntry("Version",(nVersion>lVersion)?nVersion:lVersion); + lcfg.sync(); + + } +} + +void Sidebar_Widget::buttonPopupActivate(int id) +{ + switch (id) + { + case 1: + { + KIconDialog kicd(this); +// kicd.setStrictIconSize(true); + QString iconname=kicd.selectIcon(KIcon::Small); + kdDebug()<<"New Icon Name:"<<iconname<<endl; + if (!iconname.isEmpty()) + { + KSimpleConfig ksc(m_path+m_currentButton->file); + ksc.setGroup("Desktop Entry"); + ksc.writeEntry("Icon",iconname); + ksc.sync(); + QTimer::singleShot(0,this,SLOT(updateButtons())); + } + break; + } + case 2: + { + KURLRequesterDlg * dlg = new KURLRequesterDlg( m_currentButton->URL, i18n("Enter a URL:"), this, "url_dlg" ); + dlg->fileDialog()->setMode( KFile::Directory ); + if (dlg->exec()) + { + KSimpleConfig ksc(m_path+m_currentButton->file); + ksc.setGroup("Desktop Entry"); + if ( !dlg->selectedURL().isValid()) + { + KMessageBox::error(this, i18n("<qt><b>%1</b> does not exist</qt>").arg(dlg->selectedURL().url())); + } + else + { + QString newurl= dlg->selectedURL().prettyURL(); + //If we are going to set the name by 'set name', we don't set it here. + //ksc.writeEntry("Name",newurl); + ksc.writePathEntry("URL",newurl); + ksc.sync(); + QTimer::singleShot(0,this,SLOT(updateButtons())); + } + } + delete dlg; + break; + } + case 3: + { + if (KMessageBox::warningContinueCancel(this,i18n("<qt>Do you really want to remove the <b>%1</b> tab?</qt>").arg(m_currentButton->displayName), + QString::null,KStdGuiItem::del())==KMessageBox::Continue) + { + QFile f(m_path+m_currentButton->file); + if (!f.remove()) + qDebug("Error, file not deleted"); + QTimer::singleShot(0,this,SLOT(updateButtons())); + } + break; + } + case 4: // Set a name for this sidebar tab + { + bool ok; + + // Pop up the dialog asking the user for name. + const QString name = KInputDialog::getText(i18n("Set Name"), i18n("Enter the name:"), + m_currentButton->displayName, &ok, this); + + if(ok) + { + // Write the name in the .desktop file of this side button. + KSimpleConfig ksc(m_path+m_currentButton->file); + ksc.setGroup("Desktop Entry"); + ksc.writeEntry("Name", name, true, false, true /*localized*/ ); + ksc.sync(); + + // Update the buttons with a QTimer (why?) + QTimer::singleShot(0,this,SLOT(updateButtons())); + } + break; + } + } +} + +void Sidebar_Widget::activatedMenu(int id) +{ + switch (id) + { + case 1: + { + m_singleWidgetMode = !m_singleWidgetMode; + if ((m_singleWidgetMode) && (m_visibleViews.count()>1)) + { + int tmpViewID=m_latestViewed; + for (uint i=0; i<m_buttons.count(); i++) { + ButtonInfo *button = m_buttons.at(i); + if ((int) i != tmpViewID) + { + if (button->dock && button->dock->isVisibleTo(this)) + showHidePage(i); + } else { + if (button->dock) + { + m_area->setMainDockWidget(button->dock); + m_mainDockWidget->undock(); + } + } + } + m_latestViewed=tmpViewID; + } else { + if (!m_singleWidgetMode) + { + int tmpLatestViewed=m_latestViewed; + m_area->setMainDockWidget(m_mainDockWidget); + m_mainDockWidget->setDockSite(KDockWidget::DockTop); + m_mainDockWidget->setEnableDocking(KDockWidget::DockNone); + m_mainDockWidget->show(); + if ((tmpLatestViewed>=0) && (tmpLatestViewed < (int) m_buttons.count())) + { + ButtonInfo *button = m_buttons.at(tmpLatestViewed); + if (button && button->dock) + { + m_noUpdate=true; + button->dock->undock(); + button->dock->setEnableDocking(KDockWidget::DockTop| + KDockWidget::DockBottom/*|KDockWidget::DockDesktop*/); + kdDebug()<<"Reconfiguring multi view mode"<<endl; + m_buttonBar->setTab(tmpLatestViewed,true); + showHidePage(tmpLatestViewed); + } + } + } + } + break; + } + case 2: + { + m_showTabsLeft = ! m_showTabsLeft; + doLayout(); + break; + } + case 3: + { + m_showExtraButtons = ! m_showExtraButtons; + if(m_showExtraButtons) + { + m_buttonBar->button(-1)->show(); + } + else + { + m_buttonBar->button(-1)->hide(); + + KMessageBox::information(this, + i18n("You have hidden the navigation panel configuration button. To make it visible again, click the right mouse button on any of the navigation panel buttons and select \"Show Configuration Button\".")); + + } + break; + } + default: + return; + } + m_configTimer.start(400, true); +} + +void Sidebar_Widget::readConfig() +{ + m_disableConfig = m_config->readBoolEntry("DisableConfig",false); + m_singleWidgetMode = m_config->readBoolEntry("SingleWidgetMode",true); + m_immutableSingleWidgetMode = + m_config->entryIsImmutable("SingleWidgetMode"); + m_showExtraButtons = m_config->readBoolEntry("ShowExtraButtons",false); + m_immutableShowExtraButtons = + m_config->entryIsImmutable("ShowExtraButtons"); + m_showTabsLeft = m_config->readBoolEntry("ShowTabsLeft", true); + m_immutableShowTabsLeft = m_config->entryIsImmutable("ShowTabsLeft"); + m_hideTabs = m_config->readBoolEntry("HideTabs", false); + m_immutableHideTabs = m_config->entryIsImmutable("HideTabs"); + + if (m_initial) { + m_openViews = m_config->readListEntry("OpenViews"); + m_savedWidth = m_config->readNumEntry("SavedWidth",200); + m_initial=false; + } +} + +void Sidebar_Widget::stdAction(const char *handlestd) +{ + ButtonInfo* mod = m_activeModule; + + if (!mod) + return; + if (!(mod->module)) + return; + + kdDebug() << "Try calling >active< module's (" << mod->module->className() << ") slot " << handlestd << endl; + + int id = mod->module->metaObject()->findSlot( handlestd ); + if ( id == -1 ) + return; + kdDebug() << "Action slot was found, it will be called now" << endl; + QUObject o[ 1 ]; + mod->module->qt_invoke( id, o ); + return; +} + + +void Sidebar_Widget::updateButtons() +{ + //PARSE ALL DESKTOP FILES + m_openViews = m_visibleViews; + + if (m_buttons.count() > 0) + { + for (uint i = 0; i < m_buttons.count(); i++) + { + ButtonInfo *button = m_buttons.at(i); + if (button->dock) + { + m_noUpdate = true; + if (button->dock->isVisibleTo(this)) { + showHidePage(i); + } + + delete button->module; + delete button->dock; + } + m_buttonBar->removeTab(i); + + } + } + m_buttons.clear(); + + readConfig(); + doLayout(); + createButtons(); +} + +void Sidebar_Widget::createButtons() +{ + if (!m_path.isEmpty()) + { + kdDebug()<<"m_path: "<<m_path<<endl; + QDir dir(m_path); + QStringList list=dir.entryList("*.desktop"); + for (QStringList::Iterator it=list.begin(); it!=list.end(); ++it) + { + addButton(*it); + } + } + + if (!m_buttonBar->button(-1)) { + m_buttonBar->appendButton(SmallIcon("configure"), -1, m_menu, + i18n("Configure Sidebar")); + } + + if (m_showExtraButtons && !m_disableConfig) { + m_buttonBar->button(-1)->show(); + } else { + m_buttonBar->button(-1)->hide(); + } + + for (uint i = 0; i < m_buttons.count(); i++) + { + ButtonInfo *button = m_buttons.at(i); + if (m_openViews.contains(button->file)) + { + m_buttonBar->setTab(i,true); + m_noUpdate = true; + showHidePage(i); + if (m_singleWidgetMode) { + break; + } + } + } + + collapseExpandSidebar(); + m_noUpdate=false; +} + +bool Sidebar_Widget::openURL(const class KURL &url) +{ + if (url.protocol()=="sidebar") + { + for (unsigned int i=0;i<m_buttons.count();i++) + if (m_buttons.at(i)->file==url.path()) + { + KMultiTabBarTab *tab = m_buttonBar->tab(i); + if (!tab->isOn()) + tab->animateClick(); + return true; + } + return false; + } + + m_storedUrl=url; + m_hasStoredUrl=true; + bool ret = false; + for (unsigned int i=0;i<m_buttons.count();i++) + { + ButtonInfo *button = m_buttons.at(i); + if (button->dock) + { + if ((button->dock->isVisibleTo(this)) && (button->module)) + { + ret = true; + button->module->openURL(url); + } + } + } + return ret; +} + +bool Sidebar_Widget::addButton(const QString &desktoppath,int pos) +{ + int lastbtn = m_buttons.count(); + m_buttons.resize(m_buttons.size()+1); + + KSimpleConfig *confFile; + + kdDebug() << "addButton:" << (m_path+desktoppath) << endl; + + confFile = new KSimpleConfig(m_path+desktoppath,true); + confFile->setGroup("Desktop Entry"); + + QString icon = confFile->readEntry("Icon"); + QString name = confFile->readEntry("Name"); + QString comment = confFile->readEntry("Comment"); + QString url = confFile->readPathEntry("URL",QString::null); + QString lib = confFile->readEntry("X-KDE-KonqSidebarModule"); + + delete confFile; + + if (pos == -1) + { + m_buttonBar->appendTab(SmallIcon(icon), lastbtn, name); + ButtonInfo *bi = new ButtonInfo(desktoppath, ((KonqSidebar*)m_partParent),0, url, lib, name, + icon, this); + /*int id=*/m_buttons.insert(lastbtn, bi); + KMultiTabBarTab *tab = m_buttonBar->tab(lastbtn); + tab->installEventFilter(this); + connect(tab,SIGNAL(clicked(int)),this,SLOT(showHidePage(int))); + + // Set Whats This help + // This uses the comments in the .desktop files + QWhatsThis::add(tab, comment); + } + + return true; +} + + + +bool Sidebar_Widget::eventFilter(QObject *obj, QEvent *ev) +{ + + if (ev->type()==QEvent::MouseButtonPress && ((QMouseEvent *)ev)->button()==QMouseEvent::RightButton) + { + KMultiTabBarTab *bt=dynamic_cast<KMultiTabBarTab*>(obj); + if (bt) + { + kdDebug()<<"Request for popup"<<endl; + m_currentButton = 0; + for (uint i=0;i<m_buttons.count();i++) + { + if (bt==m_buttonBar->tab(i)) + { + m_currentButton = m_buttons.at(i); + break; + } + } + + if (m_currentButton) + { + if (!m_buttonPopup) + { + m_buttonPopup=new KPopupMenu(this, "Sidebar_Widget::ButtonPopup"); + m_buttonPopup->insertTitle(SmallIcon("unknown"), "", 50); + m_buttonPopup->insertItem(SmallIconSet("text"), i18n("Set Name..."),4); // Item to open a dialog to change the name of the sidebar item (by Pupeno) + m_buttonPopup->insertItem(SmallIconSet("www"), i18n("Set URL..."),2); + m_buttonPopup->insertItem(SmallIconSet("icons"), i18n("Set Icon..."),1); + m_buttonPopup->insertSeparator(); + m_buttonPopup->insertItem(SmallIconSet("editdelete"), i18n("Remove"),3); + m_buttonPopup->insertSeparator(); + m_buttonPopup->insertItem(SmallIconSet("configure"), i18n("Configure Navigation Panel"), m_menu, 4); + connect(m_buttonPopup, SIGNAL(activated(int)), + this, SLOT(buttonPopupActivate(int))); + } + m_buttonPopup->setItemEnabled(2,!m_currentButton->URL.isEmpty()); + m_buttonPopup->changeTitle(50,SmallIcon(m_currentButton->iconName), + m_currentButton->displayName); + if (!m_disableConfig) + { m_buttonPopup->exec(QCursor::pos()); } + } + return true; + + } + } + return false; +} + +void Sidebar_Widget::mousePressEvent(QMouseEvent *ev) +{ + if (ev->type()==QEvent::MouseButtonPress && + ((QMouseEvent *)ev)->button()==QMouseEvent::RightButton && + !m_disableConfig) + { m_menu->exec(QCursor::pos()); } +} + +KonqSidebarPlugin *Sidebar_Widget::loadModule(QWidget *par,QString &desktopName,QString lib_name,ButtonInfo* bi) +{ + KLibLoader *loader = KLibLoader::self(); + + // try to load the library + KLibrary *lib = loader->library(QFile::encodeName(lib_name)); + if (lib) + { + // get the create_ function + QString factory("create_%1"); + void *create = lib->symbol(QFile::encodeName(factory.arg(lib_name))); + + if (create) + { + // create the module + + KonqSidebarPlugin* (*func)(KInstance*,QObject *, QWidget*, QString&, const char *); + func = (KonqSidebarPlugin* (*)(KInstance*,QObject *, QWidget *, QString&, const char *)) create; + QString fullPath(m_path+desktopName); + return (KonqSidebarPlugin*)func(getInstance(),bi,par,fullPath,0); + } + } else { + kdWarning() << "Module " << lib_name << " doesn't specify a library!" << endl; + } + return 0; +} + +KParts::BrowserExtension *Sidebar_Widget::getExtension() +{ + return KParts::BrowserExtension::childObject(m_partParent); +} + +bool Sidebar_Widget::createView( ButtonInfo *data) +{ + bool ret = true; + KSimpleConfig *confFile; + confFile = new KSimpleConfig(data->file,true); + confFile->setGroup("Desktop Entry"); + + data->dock = m_area->createDockWidget(confFile->readEntry("Name",i18n("Unknown")),0); + data->module = loadModule(data->dock,data->file,data->libName,data); + + if (data->module == 0) + { + delete data->dock; + data->dock = 0; + ret = false; + } else { + data->dock->setWidget(data->module->getWidget()); + data->dock->setEnableDocking(KDockWidget::DockTop| + KDockWidget::DockBottom/*|KDockWidget::DockDesktop*/); + data->dock->setDockSite(KDockWidget::DockTop|KDockWidget::DockBottom); + connectModule(data->module); + connect(this, SIGNAL(fileSelection(const KFileItemList&)), + data->module, SLOT(openPreview(const KFileItemList&))); + + connect(this, SIGNAL(fileMouseOver(const KFileItem&)), + data->module, SLOT(openPreviewOnMouseOver(const KFileItem&))); + } + + delete confFile; + return ret; +} + +void Sidebar_Widget::showHidePage(int page) +{ + ButtonInfo *info = m_buttons.at(page); + if (!info->dock) + { + if (m_buttonBar->isTabRaised(page)) + { + //SingleWidgetMode + if (m_singleWidgetMode) + { + if (m_latestViewed != -1) + { + m_noUpdate = true; + showHidePage(m_latestViewed); + } + } + + if (!createView(info)) + { + m_buttonBar->setTab(page,false); + return; + } + + m_buttonBar->setTab(page,true); + + connect(info->module, + SIGNAL(setIcon(const QString&)), + m_buttonBar->tab(page), + SLOT(setIcon(const QString&))); + + connect(info->module, + SIGNAL(setCaption(const QString&)), + m_buttonBar->tab(page), + SLOT(setText(const QString&))); + + if (m_singleWidgetMode) + { + m_area->setMainDockWidget(info->dock); + m_mainDockWidget->undock(); + } else { + info->dock->manualDock(m_mainDockWidget,KDockWidget::DockTop,100); + } + + info->dock->show(); + + if (m_hasStoredUrl) + info->module->openURL(m_storedUrl); + m_visibleViews<<info->file; + m_latestViewed=page; + } + } else { + if ((!info->dock->isVisibleTo(this)) && (m_buttonBar->isTabRaised(page))) { + //SingleWidgetMode + if (m_singleWidgetMode) { + if (m_latestViewed != -1) { + m_noUpdate = true; + showHidePage(m_latestViewed); + } + } + + if (m_singleWidgetMode) { + m_area->setMainDockWidget(info->dock); + m_mainDockWidget->undock(); + } else { + info->dock->manualDock(m_mainDockWidget,KDockWidget::DockTop,100); + } + + info->dock->show(); + m_latestViewed = page; + if (m_hasStoredUrl) + info->module->openURL(m_storedUrl); + m_visibleViews << info->file; + m_buttonBar->setTab(page,true); + } else { + m_buttonBar->setTab(page,false); + if (m_singleWidgetMode) { + m_area->setMainDockWidget(m_mainDockWidget); + m_mainDockWidget->show(); + } + info->dock->undock(); + m_latestViewed = -1; + m_visibleViews.remove(info->file); + } + } + + if (!m_noUpdate) + collapseExpandSidebar(); + m_noUpdate = false; +} + +void Sidebar_Widget::collapseExpandSidebar() +{ + if (!parentWidget()) + return; // Can happen during destruction + + if (m_visibleViews.count()==0) + { + m_somethingVisible = false; + parentWidget()->setMaximumWidth(minimumSizeHint().width()); + updateGeometry(); + emit panelHasBeenExpanded(false); + } else { + m_somethingVisible = true; + parentWidget()->setMaximumWidth(32767); + updateGeometry(); + emit panelHasBeenExpanded(true); + } +} + +QSize Sidebar_Widget::sizeHint() const +{ + if (m_somethingVisible) + return QSize(m_savedWidth,200); + return minimumSizeHint(); +} + +void Sidebar_Widget::dockWidgetHasUndocked(KDockWidget* wid) +{ + kdDebug()<<" Sidebar_Widget::dockWidgetHasUndocked(KDockWidget*)"<<endl; + for (unsigned int i=0;i<m_buttons.count();i++) + { + ButtonInfo *button = m_buttons.at(i); + if (button->dock==wid) + { + if (m_buttonBar->isTabRaised(i)) + { + m_buttonBar->setTab(i,false); + showHidePage(i); + } + } + } +} + +KInstance *Sidebar_Widget::getInstance() +{ + return ((KonqSidebar*)m_partParent)->getInstance(); +} + +void Sidebar_Widget::submitFormRequest(const char *action, + const QString& url, + const QByteArray& formData, + const QString& /*target*/, + const QString& contentType, + const QString& /*boundary*/ ) +{ +KParts::URLArgs args; + + args.setContentType("Content-Type: " + contentType); + args.postData = formData; + args.setDoPost(QCString(action).lower() == "post"); + // boundary? + emit getExtension()->openURLRequest(KURL( url ), args); +} + +void Sidebar_Widget::openURLRequest( const KURL &url, const KParts::URLArgs &args) +{ + getExtension()->openURLRequest(url,args); +} + +void Sidebar_Widget::createNewWindow( const KURL &url, const KParts::URLArgs &args) +{ + getExtension()->createNewWindow(url,args); +} + +void Sidebar_Widget::createNewWindow( const KURL &url, const KParts::URLArgs &args, + const KParts::WindowArgs &windowArgs, KParts::ReadOnlyPart *&part ) +{ + getExtension()->createNewWindow(url,args,windowArgs,part); +} + +void Sidebar_Widget::enableAction( const char * name, bool enabled ) +{ + if (sender()->parent()->isA("ButtonInfo")) + { + ButtonInfo *btninfo = static_cast<ButtonInfo*>(sender()->parent()); + if (btninfo) + { + QString n(name); + if (n == "copy") + btninfo->copy = enabled; + else if (n == "cut") + btninfo->cut = enabled; + else if (n == "paste") + btninfo->paste = enabled; + else if (n == "trash") + btninfo->trash = enabled; + else if (n == "del") + btninfo->del = enabled; + else if (n == "rename") + btninfo->rename = enabled; + } + } +} + + +bool Sidebar_Widget::doEnableActions() +{ + if (!(sender()->parent()->isA("ButtonInfo"))) + { + kdDebug()<<"Couldn't set active module, aborting"<<endl; + return false; + } else { + m_activeModule=static_cast<ButtonInfo*>(sender()->parent()); + getExtension()->enableAction( "copy", m_activeModule->copy ); + getExtension()->enableAction( "cut", m_activeModule->cut ); + getExtension()->enableAction( "paste", m_activeModule->paste ); + getExtension()->enableAction( "trash", m_activeModule->trash ); + getExtension()->enableAction( "del", m_activeModule->del ); + getExtension()->enableAction( "rename", m_activeModule->rename ); + return true; + } + +} + +void Sidebar_Widget::popupMenu( const QPoint &global, const KFileItemList &items ) +{ + if (doEnableActions()) + getExtension()->popupMenu(global,items); +} + + +void Sidebar_Widget::popupMenu( KXMLGUIClient *client, const QPoint &global, const KFileItemList &items ) +{ + if (doEnableActions()) + getExtension()->popupMenu(client,global,items); +} + +void Sidebar_Widget::popupMenu( const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode) +{ + if (doEnableActions()) + getExtension()->popupMenu(global,url,mimeType,mode); +} + +void Sidebar_Widget::popupMenu( KXMLGUIClient *client, + const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode ) +{ + if (doEnableActions()) + getExtension()->popupMenu(client,global,url,mimeType,mode); +} + +void Sidebar_Widget::connectModule(QObject *mod) +{ + if (mod->metaObject()->findSignal("started(KIO::Job*)") != -1) { + connect(mod,SIGNAL(started(KIO::Job *)),this, SIGNAL(started(KIO::Job*))); + } + + if (mod->metaObject()->findSignal("completed()") != -1) { + connect(mod,SIGNAL(completed()),this,SIGNAL(completed())); + } + + if (mod->metaObject()->findSignal("popupMenu(const QPoint&,const KURL&,const QString&,mode_t)") != -1) { + connect(mod,SIGNAL(popupMenu( const QPoint &, const KURL &, + const QString &, mode_t)),this,SLOT(popupMenu( const + QPoint &, const KURL&, const QString &, mode_t))); + } + + if (mod->metaObject()->findSignal("popupMenu(KXMLGUIClient*,const QPoint&,const KURL&,const QString&,mode_t)") != -1) { + connect(mod,SIGNAL(popupMenu( KXMLGUIClient *, const QPoint &, + const KURL &,const QString &, mode_t)),this, + SLOT(popupMenu( KXMLGUIClient *, const QPoint &, + const KURL &,const QString &, mode_t))); + } + + if (mod->metaObject()->findSignal("popupMenu(const QPoint&,const KFileItemList&)") != -1) { + connect(mod,SIGNAL(popupMenu( const QPoint &, const KFileItemList & )), + this,SLOT(popupMenu( const QPoint &, const KFileItemList & ))); + } + + if (mod->metaObject()->findSignal("openURLRequest(const KURL&,const KParts::URLArgs&)") != -1) { + connect(mod,SIGNAL(openURLRequest( const KURL &, const KParts::URLArgs &)), + this,SLOT(openURLRequest( const KURL &, const KParts::URLArgs &))); + } + + if (mod->metaObject()->findSignal("submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&)") != -1) { + connect(mod, + SIGNAL(submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&)), + this, + SLOT(submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&))); + } + + if (mod->metaObject()->findSignal("enableAction(const char*,bool)") != -1) { + connect(mod,SIGNAL(enableAction( const char *, bool)), + this,SLOT(enableAction(const char *, bool))); + } + + if (mod->metaObject()->findSignal("createNewWindow(const KURL&,const KParts::URLArgs&)") != -1) { + connect(mod,SIGNAL(createNewWindow( const KURL &, const KParts::URLArgs &)), + this,SLOT(createNewWindow( const KURL &, const KParts::URLArgs &))); + } +} + + + +Sidebar_Widget::~Sidebar_Widget() +{ + m_config->writeEntry("OpenViews", m_visibleViews); + if (m_configTimer.isActive()) + saveConfig(); + delete m_config; + m_noUpdate = true; + for (uint i=0;i<m_buttons.count();i++) + { + ButtonInfo *button = m_buttons.at(i); + if (button->dock) + button->dock->undock(); + } +} + +void Sidebar_Widget::customEvent(QCustomEvent* ev) +{ + if (KonqFileSelectionEvent::test(ev)) + { + emit fileSelection(static_cast<KonqFileSelectionEvent*>(ev)->selection()); + } else if (KonqFileMouseOverEvent::test(ev)) { + if (!(static_cast<KonqFileMouseOverEvent*>(ev)->item())) { + emit fileMouseOver(KFileItem(KURL(),QString::null,KFileItem::Unknown)); + } else { + emit fileMouseOver(*static_cast<KonqFileMouseOverEvent*>(ev)->item()); + } + } +} + +void Sidebar_Widget::resizeEvent(QResizeEvent* ev) +{ + if (m_somethingVisible && m_userMovedSplitter) + { + int newWidth = width(); + QSplitter *split = splitter(); + if (split && (m_savedWidth != newWidth)) + { + QValueList<int> sizes = split->sizes(); + if ((sizes.count() >= 2) && (sizes[1])) + { + m_savedWidth = newWidth; + updateGeometry(); + m_configTimer.start(400, true); + } + } + } + m_userMovedSplitter = false; + QWidget::resizeEvent(ev); +} + +QSplitter *Sidebar_Widget::splitter() const +{ + if (m_universalMode) return 0; + QObject *p = parent(); + if (!p) return 0; + p = p->parent(); + return static_cast<QSplitter*>(p); +} + +void Sidebar_Widget::userMovedSplitter() +{ + m_userMovedSplitter = true; +} diff --git a/konqueror/sidebar/sidebar_widget.h b/konqueror/sidebar/sidebar_widget.h new file mode 100644 index 000000000..ccaba5224 --- /dev/null +++ b/konqueror/sidebar/sidebar_widget.h @@ -0,0 +1,225 @@ +/*************************************************************************** + sidebar_widget.h + ------------------- + begin : Sat June 2 16:25:27 CEST 2001 + copyright : (C) 2001 Joseph Wenninger + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef _SIDEBAR_WIDGET_ +#define _SIDEBAR_WIDGET_ + +#include <qptrvector.h> +#include <qtimer.h> +#include <qstring.h> +#include <qguardedptr.h> + +#include <kdockwidget.h> +#include <kurl.h> +#include <ktoolbar.h> +#include <kparts/part.h> +#include <kmultitabbar.h> + +#include "konqsidebarplugin.h" +#include "konqsidebariface_p.h" + +class KDockWidget; +class QHBoxLayout; +class QSplitter; +class QStringList; + +class ButtonInfo: public QObject, public KonqSidebarIface +{ + Q_OBJECT +public: + ButtonInfo(const QString& file_, class KonqSidebarIface *part, class KDockWidget *dock_, + const QString &url_,const QString &lib, + const QString &dispName_, const QString &iconName_, + QObject *parent) + : QObject(parent), file(file_), dock(dock_), URL(url_), + libName(lib), displayName(dispName_), iconName(iconName_), m_part(part) + { + copy = cut = paste = trash = del = rename =false; + } + + ~ButtonInfo() {} + + QString file; + KDockWidget *dock; + KonqSidebarPlugin *module; + QString URL; + QString libName; + QString displayName; + QString iconName; + bool copy; + bool cut; + bool paste; + bool trash; + bool del; + bool rename; + KonqSidebarIface *m_part; + virtual bool universalMode() {return m_part->universalMode();} +}; + + +class addBackEnd: public QObject +{ + Q_OBJECT +public: + addBackEnd(QWidget *parent,class QPopupMenu *addmenu, bool universal, + const QString ¤tProfile, const char *name=0); + ~addBackEnd(){;} +protected slots: + void aboutToShowAddMenu(); + void activatedAddMenu(int); +signals: + void updateNeeded(); + void initialCopyNeeded(); +private: + QGuardedPtr<class QPopupMenu> menu; + QPtrVector<QString> libNames; + QPtrVector<QString> libParam; + bool m_universal; + QString m_currentProfile; + void doRollBack(); + QWidget *m_parent; +}; + +class KDE_EXPORT Sidebar_Widget: public QWidget +{ + Q_OBJECT +public: + friend class ButtonInfo; +public: + Sidebar_Widget(QWidget *parent, KParts::ReadOnlyPart *par, + const char * name,bool universalMode, + const QString ¤tProfile); + ~Sidebar_Widget(); + bool openURL(const class KURL &url); + void stdAction(const char *handlestd); + //virtual KParts::ReadOnlyPart *getPart(); + KParts::BrowserExtension *getExtension(); + virtual QSize sizeHint() const; + +public slots: + void addWebSideBar(const KURL& url, const QString& name); + +protected: + void customEvent(QCustomEvent* ev); + void resizeEvent(QResizeEvent* ev); + virtual bool eventFilter(QObject*,QEvent*); + virtual void mousePressEvent(QMouseEvent*); + +protected slots: + void showHidePage(int value); + void createButtons(); + void updateButtons(); + void finishRollBack(); + void activatedMenu(int id); + void buttonPopupActivate(int); + void dockWidgetHasUndocked(KDockWidget*); + void aboutToShowConfigMenu(); + void saveConfig(); + +signals: + void started(KIO::Job *); + void completed(); + void fileSelection(const KFileItemList& iems); + void fileMouseOver(const KFileItem& item); + +public: + /* interface KonqSidebar_PluginInterface*/ + KInstance *getInstance(); +// virtual void showError(QString &); for later extension +// virtual void showMessage(QString &); for later extension + /* end of interface implementation */ + + + /* The following public slots are wrappers for browserextension fields */ +public slots: + void openURLRequest( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + /* @internal + * @since 3.2 + * ### KDE4 remove me + */ + void submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&); + void createNewWindow( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + void createNewWindow( const KURL &url, const KParts::URLArgs &args, + const KParts::WindowArgs &windowArgs, KParts::ReadOnlyPart *&part ); + + void popupMenu( const QPoint &global, const KFileItemList &items ); + void popupMenu( KXMLGUIClient *client, const QPoint &global, const KFileItemList &items ); + void popupMenu( const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode = (mode_t)-1 ); + void popupMenu( KXMLGUIClient *client, + const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode = (mode_t)-1 ); + void enableAction( const char * name, bool enabled ); + void userMovedSplitter(); + +private: + QSplitter *splitter() const; + bool addButton(const QString &desktoppath,int pos=-1); + bool createView(ButtonInfo *data); + KonqSidebarPlugin *loadModule(QWidget *par,QString &desktopName,QString lib_name,ButtonInfo *bi); + void readConfig(); + void initialCopy(); + void doLayout(); + void connectModule(QObject *mod); + void collapseExpandSidebar(); + bool doEnableActions(); + bool m_universalMode; + bool m_userMovedSplitter; +private: + KParts::ReadOnlyPart *m_partParent; + KDockArea *m_area; + KDockWidget *m_mainDockWidget; + + KMultiTabBar *m_buttonBar; + QPtrVector<ButtonInfo> m_buttons; + QHBoxLayout *m_layout; + KPopupMenu *m_buttonPopup; + QPopupMenu *m_menu; + QGuardedPtr<ButtonInfo> m_activeModule; + QGuardedPtr<ButtonInfo> m_currentButton; + + KConfig *m_config; + QTimer m_configTimer; + + KURL m_storedUrl; + int m_savedWidth; + int m_latestViewed; + + bool m_hasStoredUrl; + bool m_singleWidgetMode; + bool m_immutableSingleWidgetMode; + bool m_showTabsLeft; + bool m_immutableShowTabsLeft; + bool m_hideTabs; + bool m_immutableHideTabs; + bool m_disableConfig; + bool m_showExtraButtons; + bool m_immutableShowExtraButtons; + bool m_somethingVisible; + bool m_noUpdate; + bool m_initial; + + QString m_path; + QString m_relPath; + QString m_currentProfile; + QStringList m_visibleViews; // The views that are actually open + QStringList m_openViews; // The views that should be opened + +signals: + void panelHasBeenExpanded(bool); +}; + +#endif diff --git a/konqueror/sidebar/test/Makefile.am b/konqueror/sidebar/test/Makefile.am new file mode 100644 index 000000000..ebaeff299 --- /dev/null +++ b/konqueror/sidebar/test/Makefile.am @@ -0,0 +1,23 @@ +# this has all of the subdirectories that make will recurse into. if +# there are none, comment this out +SUBDIRS = . + +# set the include path for X, qt and KDE +INCLUDES = -I$(srcdir)/.. $(all_includes) + +# these are the headers for your project +noinst_HEADERS = konqsidebartest.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +kde_module_LTLIBRARIES = konq_sidebartest.la + +# the Part's source, library search path, and link libraries +konq_sidebartest_la_SOURCES = konqsidebartest.cpp +konq_sidebartest_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +konq_sidebartest_la_LIBADD = $(LIB_KPARTS) $(LIB_KIO) ../libkonqsidebarplugin.la + +# this is where the part's XML-GUI resource file goes +partrcdir = $(kde_datadir)/konqsidebartng/entries +partrc_DATA = test.desktop diff --git a/konqueror/sidebar/test/konqsidebartest.cpp b/konqueror/sidebar/test/konqsidebartest.cpp new file mode 100644 index 000000000..56dfff2fe --- /dev/null +++ b/konqueror/sidebar/test/konqsidebartest.cpp @@ -0,0 +1,26 @@ +/*************************************************************************** + konqsidebartest.cpp + ------------------- + begin : Sat June 2 16:25:27 CEST 2001 + copyright : (C) 2001 Joseph Wenninger + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "konqsidebartest.moc" +#include <kinstance.h> + +extern "C" +{ + KDE_EXPORT void* create_konq_sidebartest(KInstance *instance,QObject *par,QWidget *widp,QString &desktopname,const char *name) + { + return new SidebarTest(instance,par,widp,desktopname,name); + } +}; diff --git a/konqueror/sidebar/test/konqsidebartest.h b/konqueror/sidebar/test/konqsidebartest.h new file mode 100644 index 000000000..0c304e949 --- /dev/null +++ b/konqueror/sidebar/test/konqsidebartest.h @@ -0,0 +1,43 @@ +/*************************************************************************** + konqsidebartest.h + ------------------- + begin : Sat June 2 16:25:27 CEST 2001 + copyright : (C) 2001 Joseph Wenninger + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef _konq_sidebar_test_h_ +#define _konq_sidebar_test_h_ +#include <konqsidebarplugin.h> +#include <qlabel.h> +#include <qlayout.h> + +class SidebarTest : public KonqSidebarPlugin + { + Q_OBJECT + public: + SidebarTest(KInstance *inst,QObject *parent,QWidget *widgetParent, QString &desktopName_, const char* name=0): + KonqSidebarPlugin(inst,parent,widgetParent,desktopName_,name) + { + widget=new QLabel("Init Value",widgetParent); + } + ~SidebarTest(){;} + virtual QWidget *getWidget(){return widget;} + virtual void *provides(const QString &) {return 0;} + protected: + QLabel *widget; + virtual void handleURL(const KURL &url) + { + widget->setText(url.url()); + } + }; + +#endif diff --git a/konqueror/sidebar/test/test.desktop b/konqueror/sidebar/test/test.desktop new file mode 100644 index 000000000..9ede79467 --- /dev/null +++ b/konqueror/sidebar/test/test.desktop @@ -0,0 +1,68 @@ +[Desktop Entry] +Type=Link +URL= +Icon=wizard +Name=Test +Name[af]=Toets +Name[ar]=إختبار +Name[az]=Sınaq +Name[be]=Праверка +Name[bg]=Проба +Name[bn]=পরীক্ষা +Name[br]=Arnodiñ +Name[bs]=Proba +Name[ca]=Prova +Name[cy]=Arbrofi +Name[el]=Δοκιμή +Name[eo]=Testo +Name[es]=Prueba +Name[eu]=Froga +Name[fa]=آزمون +Name[fi]=Testi +Name[ga]=Tástáil +Name[gl]=Probar +Name[he]=ניסיון +Name[hi]=जांच +Name[hu]=Próba +Name[id]=Tes +Name[is]=Prufa +Name[it]=Prova +Name[ja]=テスト +Name[ka]=ტესტი +Name[kk]=Сынау +Name[km]=សាកល្បង +Name[ko]=시험 +Name[lo]=ທົດສອບ +Name[lt]=Testas +Name[lv]=Tests +Name[mk]=Тест +Name[mn]=Тест +Name[ms]=Uji +Name[ne]=परीक्षण +Name[nso]=Teko +Name[pa]=ਜਾਂਚ +Name[pt]=Teste +Name[pt_BR]=Testar +Name[ru]=Тест +Name[rw]=Isuzuma +Name[se]=Geahččaleapmi +Name[sl]=Preizkus +Name[sr]=Тест +Name[ta]=சோதனை +Name[te]=పరీక్ష +Name[tg]=Озмоиш +Name[th]=ทดสอบ +Name[tt]=Sınaw +Name[uk]=Тест +Name[uz]=Sinov +Name[uz@cyrillic]=Синов +Name[ven]=Mulingo +Name[vi]=Thử +Name[wa]=Sayî +Name[xh]=Uvavanyo +Name[zh_CN]=测试 +Name[zh_TW]=測試 +Name[zu]=Isivivinyo + +Open=false +X-KDE-KonqSidebarModule=konq_sidebartest diff --git a/konqueror/sidebar/trees/Makefile.am b/konqueror/sidebar/trees/Makefile.am new file mode 100644 index 000000000..68257b8a9 --- /dev/null +++ b/konqueror/sidebar/trees/Makefile.am @@ -0,0 +1,17 @@ +#SUBDIRS = init dirtree_module history_module bookmark_module . +SUBDIRS = init . dirtree_module history_module bookmark_module + +INCLUDES = -I$(top_srcdir)/libkonq -I$(top_srcdir)/konqueror -I$(srcdir)/.. $(all_includes) + +noinst_LTLIBRARIES = libkonq_sidebar_tree.la +kde_module_LTLIBRARIES = konqsidebar_tree.la +METASOURCES = AUTO + +libkonq_sidebar_tree_la_SOURCES = konq_sidebartree.cpp konq_sidebartreeitem.cpp konq_sidebartreetoplevelitem.cpp +#libkonq_sidebar_tree_la_LDFLAGS = $(all_libraries) -avoid-version -no-undefined +libkonq_sidebar_tree_la_LIBADD = $(top_builddir)/libkonq/libkonq.la ../libkonqsidebarplugin.la + +konqsidebar_tree_la_SOURCES = konqsidebar_tree.cpp +konqsidebar_tree_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +konqsidebar_tree_la_LIBADD = $(top_builddir)/libkonq/libkonq.la ../libkonqsidebarplugin.la libkonq_sidebar_tree.la + diff --git a/konqueror/sidebar/trees/bookmark_module/Makefile.am b/konqueror/sidebar/trees/bookmark_module/Makefile.am new file mode 100644 index 000000000..740c03798 --- /dev/null +++ b/konqueror/sidebar/trees/bookmark_module/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/libkonq -I$(srcdir)/.. -I$(srcdir)/../.. $(all_includes) + +kde_module_LTLIBRARIES = konq_sidebartree_bookmarks.la + +METASOURCES = AUTO + +konq_sidebartree_bookmarks_la_SOURCES = bookmark_module.cpp bookmark_item.cpp +konq_sidebartree_bookmarks_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +konq_sidebartree_bookmarks_la_LIBADD = ../../libkonqsidebarplugin.la ../libkonq_sidebar_tree.la + diff --git a/konqueror/sidebar/trees/bookmark_module/bookmark_item.cpp b/konqueror/sidebar/trees/bookmark_module/bookmark_item.cpp new file mode 100644 index 000000000..c0fae56cc --- /dev/null +++ b/konqueror/sidebar/trees/bookmark_module/bookmark_item.cpp @@ -0,0 +1,81 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "bookmark_item.h" +#include <kbookmarkdrag.h> +#include <konq_sidebartree.h> +#include <kdebug.h> +#include <kiconloader.h> + +#include "bookmark_module.h" + +#define MYMODULE static_cast<KonqSidebarBookmarkModule*>(module()) + +KonqSidebarBookmarkItem::KonqSidebarBookmarkItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem, const KBookmark & bk, int key ) + : KonqSidebarTreeItem( parentItem, topLevelItem ), m_bk(bk), m_key(key) +{ + setText( 0, bk.text() ); + setPixmap( 0, SmallIcon(bk.icon()) ); +} + +QDragObject * KonqSidebarBookmarkItem::dragObject( QWidget * parent, bool ) +{ + KBookmarkDrag * drag = KBookmarkDrag::newDrag( m_bk, parent ); + // TODO honour bool move ? + return drag; +} + +void KonqSidebarBookmarkItem::middleButtonClicked() +{ + emit tree()->createNewWindow( externalURL() ); +} + +void KonqSidebarBookmarkItem::rightButtonPressed() +{ + MYMODULE->showPopupMenu(); +} + +void KonqSidebarBookmarkItem::del() +{ + //maybe todo +} + +KURL KonqSidebarBookmarkItem::externalURL() const +{ + return m_bk.isGroup() ? KURL() : m_bk.url(); +} + +QString KonqSidebarBookmarkItem::toolTipText() const +{ + return m_bk.url().prettyURL(); +} + +void KonqSidebarBookmarkItem::itemSelected() +{ + tree()->enableActions( false, false, false, false, false, false ); +} + +QString KonqSidebarBookmarkItem::key( int /*column*/, bool /*ascending*/ ) const +{ + return QString::number(m_key).rightJustify( 5, '0' ); +} + +KBookmark &KonqSidebarBookmarkItem::bookmark() +{ + return m_bk; +} diff --git a/konqueror/sidebar/trees/bookmark_module/bookmark_item.h b/konqueror/sidebar/trees/bookmark_module/bookmark_item.h new file mode 100644 index 000000000..5ffe953e8 --- /dev/null +++ b/konqueror/sidebar/trees/bookmark_module/bookmark_item.h @@ -0,0 +1,62 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef bookmark_item_h +#define bookmark_item_h + +#include <konq_sidebartreeitem.h> +#include <kbookmark.h> + +/** + * A bookmark item + */ +class KonqSidebarBookmarkItem : public KonqSidebarTreeItem +{ +public: + KonqSidebarBookmarkItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem, + const KBookmark & bk, int key ); + + virtual ~KonqSidebarBookmarkItem() {} + + // Create a drag object from this item. + virtual QDragObject * dragObject( QWidget * parent, bool move = false ); + + virtual void middleButtonClicked(); + virtual void rightButtonPressed(); + + virtual void del(); + + // The URL to open when this link is clicked + virtual KURL externalURL() const; + + // overwrite this if you want a tooltip shown on your item + virtual QString toolTipText() const; + + // Called when this item is selected + virtual void itemSelected(); + + virtual QString key( int column, bool /*ascending*/ ) const; + + virtual KBookmark &bookmark(); + +private: + KBookmark m_bk; + int m_key; +}; + +#endif diff --git a/konqueror/sidebar/trees/bookmark_module/bookmark_module.cpp b/konqueror/sidebar/trees/bookmark_module/bookmark_module.cpp new file mode 100644 index 000000000..a931ac526 --- /dev/null +++ b/konqueror/sidebar/trees/bookmark_module/bookmark_module.cpp @@ -0,0 +1,583 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qclipboard.h> +#include <qcursor.h> +#include <qpopupmenu.h> + +#include <kaction.h> +#include <kactioncollection.h> +#include <kapplication.h> +#include <kbookmarkdrag.h> +#include <kiconloader.h> +#include <klineedit.h> +#include <kmessagebox.h> + +#include <dcopclient.h> +#include <dcopref.h> + +#include "bookmark_module.h" +#include "bookmark_item.h" +#include <konqbookmarkmanager.h> +#include <kdebug.h> + +KonqSidebarBookmarkModule::KonqSidebarBookmarkModule( KonqSidebarTree * parentTree ) + : QObject( 0L ), KonqSidebarTreeModule( parentTree ), + m_topLevelItem( 0L ), m_ignoreOpenChange(true) +{ + // formats handled by KBookmarkDrag: + QStringList formats; + formats << "text/uri-list" << "application/x-xbel" << "text/plain"; + tree()->setDropFormats(formats); + + connect(tree(), SIGNAL(moved(QListViewItem*,QListViewItem*,QListViewItem*)), + this, SLOT(slotMoved(QListViewItem*,QListViewItem*,QListViewItem*))); + connect(tree(), SIGNAL(dropped(KListView*,QDropEvent*,QListViewItem*,QListViewItem*)), + this, SLOT(slotDropped(KListView*,QDropEvent*,QListViewItem*,QListViewItem*))); + + connect(tree(), SIGNAL(expanded(QListViewItem*)), + this, SLOT(slotOpenChange(QListViewItem*))); + connect(tree(), SIGNAL(collapsed(QListViewItem*)), + this, SLOT(slotOpenChange(QListViewItem*))); + + m_collection = new KActionCollection( this, "bookmark actions" ); + (void) new KAction( i18n("&Create New Folder"), "folder_new", 0, this, + SLOT( slotCreateFolder() ), m_collection, "create_folder"); + (void) new KAction( i18n("Delete Folder"), "editdelete", 0, this, + SLOT( slotDelete() ), m_collection, "delete_folder"); + (void) new KAction( i18n("Delete Bookmark"), "editdelete", 0, this, + SLOT( slotDelete() ), m_collection, "delete_bookmark"); + (void) new KAction( i18n("Properties"), "edit", 0, this, + SLOT( slotProperties() ), m_collection, "item_properties"); + (void) new KAction( i18n("Open in New Window"), "window_new", 0, this, + SLOT( slotOpenNewWindow() ), m_collection, "open_window"); + (void) new KAction( i18n("Open in New Tab"), "tab_new", 0, this, + SLOT( slotOpenTab() ), m_collection, "open_tab"); + (void) new KAction( i18n("Open Folder in Tabs"), "tab_new", 0, this, + SLOT( slotOpenTab() ), m_collection, "folder_open_tabs"); + (void) new KAction( i18n("Copy Link Address"), "editcopy", 0, this, + SLOT( slotCopyLocation() ), m_collection, "copy_location"); + + KStdAction::editBookmarks( KonqBookmarkManager::self(), SLOT( slotEditBookmarks() ), + m_collection, "edit_bookmarks" ); + + connect( KonqBookmarkManager::self(), SIGNAL(changed(const QString &, const QString &) ), + SLOT( slotBookmarksChanged(const QString &) ) ); +} + +KonqSidebarBookmarkModule::~KonqSidebarBookmarkModule() +{ +} + +void KonqSidebarBookmarkModule::addTopLevelItem( KonqSidebarTreeTopLevelItem * item ) +{ + m_ignoreOpenChange = true; + + m_topLevelItem = item; + fillListView(); + + m_ignoreOpenChange = false; +} + +bool KonqSidebarBookmarkModule::handleTopLevelContextMenu( KonqSidebarTreeTopLevelItem *, const QPoint& ) +{ + QPopupMenu *menu = new QPopupMenu; + + if (tree()->tabSupport()) { + m_collection->action("folder_open_tabs")->plug(menu); + menu->insertSeparator(); + } + m_collection->action("create_folder")->plug(menu); + + menu->insertSeparator(); + m_collection->action("edit_bookmarks")->plug(menu); + + menu->exec( QCursor::pos() ); + delete menu; + + return true; +} + +void KonqSidebarBookmarkModule::showPopupMenu() +{ + KonqSidebarBookmarkItem *bi = dynamic_cast<KonqSidebarBookmarkItem*>( tree()->selectedItem() ); + if (!bi) + return; + + bool tabSupported = tree()->tabSupport(); + QPopupMenu *menu = new QPopupMenu; + + if (bi->bookmark().isGroup()) { + if (tabSupported) { + m_collection->action("folder_open_tabs")->plug(menu); + menu->insertSeparator(); + } + m_collection->action("create_folder")->plug(menu); + m_collection->action("delete_folder")->plug(menu); + } else { + m_collection->action("open_window")->plug(menu); + if (tabSupported) + m_collection->action("open_tab")->plug(menu); + m_collection->action("copy_location")->plug(menu); + menu->insertSeparator(); + m_collection->action("create_folder")->plug(menu); + m_collection->action("delete_bookmark")->plug(menu); + } + menu->insertSeparator(); + m_collection->action("item_properties")->plug(menu); + + menu->exec( QCursor::pos() ); + delete menu; +} + +void KonqSidebarBookmarkModule::slotMoved(QListViewItem *i, QListViewItem*, QListViewItem *after) +{ + KonqSidebarBookmarkItem *item = dynamic_cast<KonqSidebarBookmarkItem*>( i ); + if (!item) + return; + KBookmark bookmark = item->bookmark(); + + KBookmark afterBookmark; + KonqSidebarBookmarkItem *afterItem = dynamic_cast<KonqSidebarBookmarkItem*>(after); + if (afterItem) + afterBookmark = afterItem->bookmark(); + + KBookmarkGroup oldParentGroup = bookmark.parentGroup(); + KBookmarkGroup parentGroup; + // try to get the parent group (assume that the QListViewItem has been reparented by KListView)... + // if anything goes wrong, use the root. + if (item->parent()) { + bool error = false; + + KonqSidebarBookmarkItem *parent = dynamic_cast<KonqSidebarBookmarkItem*>( (item->parent()) ); + if (!parent) { + error = true; + } else { + if (parent->bookmark().isGroup()) + parentGroup = parent->bookmark().toGroup(); + else + error = true; + } + + if (error) + parentGroup = KonqBookmarkManager::self()->root(); + } else { + // No parent! This means the user dropped it before the top level item + // And KListView has moved the item there, we need to correct it + tree()->moveItem(item, m_topLevelItem, 0L); + parentGroup = KonqBookmarkManager::self()->root(); + } + + // remove the old reference. + oldParentGroup.deleteBookmark( bookmark ); + + // insert the new item. + parentGroup.moveItem(bookmark, afterBookmark); + + // inform others about the changed groups. quite expensive, so do + // our best to update them in only one emitChanged call. + QString oldAddress = oldParentGroup.address(); + QString newAddress = parentGroup.address(); + if (oldAddress == newAddress) { + KonqBookmarkManager::self()->emitChanged( parentGroup ); + } else { + int i = 0; + while (true) { + QChar c1 = oldAddress[i]; + QChar c2 = newAddress[i]; + if (c1 == QChar::null) { + // oldParentGroup is probably parent of parentGroup. + KonqBookmarkManager::self()->emitChanged( oldParentGroup ); + break; + } else if (c2 == QChar::null) { + // parentGroup is probably parent of oldParentGroup. + KonqBookmarkManager::self()->emitChanged( parentGroup ); + break; + } else { + if (c1 == c2) { + // step to the next character. + ++i; + } else { + // ugh... need to update both groups separately. + KonqBookmarkManager::self()->emitChanged( oldParentGroup ); + KonqBookmarkManager::self()->emitChanged( parentGroup ); + break; + } + } + } + } +} + +void KonqSidebarBookmarkModule::slotDropped(KListView *, QDropEvent *e, QListViewItem *parent, QListViewItem *after) +{ + if (!KBookmarkDrag::canDecode(e)) + return; + + KBookmark afterBookmark; + KonqSidebarBookmarkItem *afterItem = dynamic_cast<KonqSidebarBookmarkItem*>(after); + if (afterItem) + afterBookmark = afterItem->bookmark(); + + KBookmarkGroup parentGroup; + // try to get the parent group... + if (after) { + parentGroup = afterBookmark.parentGroup(); + } else if (parent) { + if(KonqSidebarBookmarkItem *p = dynamic_cast<KonqSidebarBookmarkItem*>(parent)) + { + if (!p) + return; + KBookmark bm = p->bookmark(); + if (bm.isGroup()) + parentGroup = bm.toGroup(); + else + return; + } + else if(parent == m_topLevelItem) + { + parentGroup = KonqBookmarkManager::self()->root(); + } + } else { + // it's most probably the root... + parentGroup = KonqBookmarkManager::self()->root(); + } + + QValueList<KBookmark> bookmarks = KBookmarkDrag::decode(e); + + // copy + QValueList<KBookmark>::iterator it = bookmarks.begin(); + for (;it != bookmarks.end(); ++it) { + // insert new item. + parentGroup.moveItem(*it, afterBookmark); + } + + KonqBookmarkManager::self()->emitChanged( parentGroup ); +} + +void KonqSidebarBookmarkModule::slotCreateFolder() +{ + KonqSidebarBookmarkItem *bi = dynamic_cast<KonqSidebarBookmarkItem*>( tree()->selectedItem() ); + KBookmarkGroup parentGroup; + if (bi) + { + if (bi->bookmark().isGroup()) + parentGroup = bi->bookmark().toGroup(); + else + parentGroup = bi->bookmark().parentGroup(); + } + else if(tree()->selectedItem() == m_topLevelItem) + { + parentGroup = KonqBookmarkManager::self()->root(); + } + else + return; + + KBookmark bookmark = parentGroup.createNewFolder(KonqBookmarkManager::self()); + if(bi && !(bi->bookmark().isGroup())) + parentGroup.moveItem(bookmark, bi->bookmark()); + + KonqBookmarkManager::self()->emitChanged( parentGroup ); +} + +void KonqSidebarBookmarkModule::slotDelete() +{ + KonqSidebarBookmarkItem *bi = dynamic_cast<KonqSidebarBookmarkItem*>( tree()->selectedItem() ); + if (!bi) + return; + + KBookmark bookmark = bi->bookmark(); + bool folder = bookmark.isGroup(); + + if (KMessageBox::warningYesNo( + tree(), + folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?").arg(bookmark.text()) + : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?").arg(bookmark.text()), + folder ? i18n("Bookmark Folder Deletion") + : i18n("Bookmark Deletion"), + KGuiItem( i18n("&Delete"), "editdelete"), KStdGuiItem::cancel()) + != KMessageBox::Yes + ) + return; + + KBookmarkGroup parentBookmark = bookmark.parentGroup(); + parentBookmark.deleteBookmark( bookmark ); + + KonqBookmarkManager::self()->emitChanged( parentBookmark ); +} + +void makeTextNodeMod(KBookmark bk, const QString &m_nodename, const QString &m_newText) { + QDomNode subnode = bk.internalElement().namedItem(m_nodename); + if (subnode.isNull()) { + subnode = bk.internalElement().ownerDocument().createElement(m_nodename); + bk.internalElement().appendChild(subnode); + } + + if (subnode.firstChild().isNull()) { + QDomText domtext = subnode.ownerDocument().createTextNode(""); + subnode.appendChild(domtext); + } + + QDomText domtext = subnode.firstChild().toText(); + + QString m_oldText = domtext.data(); + domtext.setData(m_newText); +} + +void KonqSidebarBookmarkModule::slotProperties(KonqSidebarBookmarkItem *bi) +{ + if (!bi) { + bi = dynamic_cast<KonqSidebarBookmarkItem*>( tree()->selectedItem() ); + if (!bi) + return; + } + + KBookmark bookmark = bi->bookmark(); + + QString folder = bookmark.isGroup() ? QString::null : bookmark.url().pathOrURL(); + BookmarkEditDialog dlg( bookmark.fullText(), folder, 0, 0, + i18n("Bookmark Properties") ); + if ( dlg.exec() != KDialogBase::Accepted ) + return; + + makeTextNodeMod(bookmark, "title", dlg.finalTitle()); + if ( !dlg.finalUrl().isNull() ) + { + KURL u = KURL::fromPathOrURL(dlg.finalUrl()); + bookmark.internalElement().setAttribute("href", u.url(0, 106)); + } + + KBookmarkGroup parentBookmark = bookmark.parentGroup(); + KonqBookmarkManager::self()->emitChanged( parentBookmark ); +} + +void KonqSidebarBookmarkModule::slotOpenNewWindow() +{ + KonqSidebarBookmarkItem *bi = dynamic_cast<KonqSidebarBookmarkItem*>( tree()->selectedItem() ); + if (!bi) + return; + + emit tree()->createNewWindow( bi->bookmark().url() ); +} + +void KonqSidebarBookmarkModule::slotOpenTab() +{ + KonqSidebarBookmarkItem *bi = dynamic_cast<KonqSidebarBookmarkItem*>( tree()->selectedItem() ); + KBookmark bookmark; + if (bi) + { + bookmark = bi->bookmark(); + } + else if(tree()->selectedItem() == m_topLevelItem) + bookmark = KonqBookmarkManager::self()->root(); + else + return; + + DCOPRef ref(kapp->dcopClient()->appId(), tree()->topLevelWidget()->name()); + + if (bookmark.isGroup()) { + KBookmarkGroup group = bookmark.toGroup(); + bookmark = group.first(); + while (!bookmark.isNull()) { + if (!bookmark.isGroup() && !bookmark.isSeparator()) + ref.call( "newTab(QString)", bookmark.url().url() ); + bookmark = group.next(bookmark); + } + } else { + ref.call( "newTab(QString)", bookmark.url().url() ); + } +} + +void KonqSidebarBookmarkModule::slotCopyLocation() +{ + KonqSidebarBookmarkItem *bi = dynamic_cast<KonqSidebarBookmarkItem*>( tree()->selectedItem() ); + if (!bi) + return; + + KBookmark bookmark = bi->bookmark(); + + if ( !bookmark.isGroup() ) + { + kapp->clipboard()->setData( KBookmarkDrag::newDrag(bookmark, 0), + QClipboard::Selection ); + kapp->clipboard()->setData( KBookmarkDrag::newDrag(bookmark, 0), + QClipboard::Clipboard ); + } +} + +void KonqSidebarBookmarkModule::slotOpenChange(QListViewItem* i) +{ + if (m_ignoreOpenChange) + return; + + KonqSidebarBookmarkItem *bi = dynamic_cast<KonqSidebarBookmarkItem*>( i ); + if (!bi) + return; + + KBookmark bookmark = bi->bookmark(); + + bool open = bi->isOpen(); + + if (!open) + m_folderOpenState.remove(bookmark.address()); // no need to store closed folders... + else + m_folderOpenState[bookmark.address()] = open; +} + +void KonqSidebarBookmarkModule::slotBookmarksChanged( const QString & groupAddress ) +{ + m_ignoreOpenChange = true; + + // update the right part of the tree + KBookmarkGroup group = KonqBookmarkManager::self()->findByAddress( groupAddress ).toGroup(); + KonqSidebarBookmarkItem * item = findByAddress( groupAddress ); + Q_ASSERT(!group.isNull()); + Q_ASSERT(item); + if (!group.isNull() && item) + { + // Delete all children of item + QListViewItem * child = item->firstChild(); + while( child ) { + QListViewItem * next = child->nextSibling(); + delete child; + child = next; + } + fillGroup( item, group ); + } + + m_ignoreOpenChange = false; +} + +void KonqSidebarBookmarkModule::fillListView() +{ + m_ignoreOpenChange = true; + + KBookmarkGroup root = KonqBookmarkManager::self()->root(); + fillGroup( m_topLevelItem, root ); + + m_ignoreOpenChange = false; +} + +void KonqSidebarBookmarkModule::fillGroup( KonqSidebarTreeItem * parentItem, KBookmarkGroup group ) +{ + int n = 0; + for ( KBookmark bk = group.first() ; !bk.isNull() ; bk = group.next(bk), ++n ) + { + KonqSidebarBookmarkItem * item = new KonqSidebarBookmarkItem( parentItem, m_topLevelItem, bk, n ); + if ( bk.isGroup() ) + { + KBookmarkGroup grp = bk.toGroup(); + fillGroup( item, grp ); + + QString address(grp.address()); + if (m_folderOpenState.contains(address)) + item->setOpen(m_folderOpenState[address]); + else + item->setOpen(false); + } + else if ( bk.isSeparator() ) + item->setVisible( false ); + else + item->setExpandable( false ); + } +} + +// Borrowed from KEditBookmarks +KonqSidebarBookmarkItem * KonqSidebarBookmarkModule::findByAddress( const QString & address ) const +{ + QListViewItem * item = m_topLevelItem; + // The address is something like /5/10/2 + QStringList addresses = QStringList::split('/',address); + for ( QStringList::Iterator it = addresses.begin() ; it != addresses.end() ; ++it ) + { + uint number = (*it).toUInt(); + item = item->firstChild(); + for ( uint i = 0 ; i < number ; ++i ) + item = item->nextSibling(); + } + Q_ASSERT(item); + return static_cast<KonqSidebarBookmarkItem *>(item); +} + +// Borrowed&modified from KBookmarkMenu... +BookmarkEditDialog::BookmarkEditDialog(const QString& title, const QString& url, + QWidget * parent, const char * name, const QString& caption ) + : KDialogBase(parent, name, true, caption, + (Ok|Cancel), + Ok, false, KGuiItem()), + m_title(0), m_location(0) +{ + setButtonOK( i18n( "&Update" ) ); + + QWidget *main = new QWidget( this ); + setMainWidget( main ); + + bool folder = url.isNull(); + QGridLayout *grid = new QGridLayout( main, 2, folder?1:2, spacingHint() ); + + QLabel *nameLabel = new QLabel(i18n("Name:"), main, "title label"); + grid->addWidget(nameLabel, 0, 0); + m_title = new KLineEdit(main, "title edit"); + m_title->setText(title); + nameLabel->setBuddy(m_title); + grid->addWidget(m_title, 0, 1); + if(!folder) { + QLabel *locationLabel = new QLabel(i18n("Location:"), main, "location label"); + grid->addWidget(locationLabel, 1, 0); + m_location = new KLineEdit(main, "location edit"); + m_location->setText(url); + locationLabel->setBuddy(m_location); + grid->addWidget(m_location, 1, 1); + } + main->setMinimumSize( 300, 0 ); +} + +void BookmarkEditDialog::slotOk() +{ + accept(); +} + +void BookmarkEditDialog::slotCancel() +{ + reject(); +} + +QString BookmarkEditDialog::finalUrl() const +{ + if (m_location!=0) + return m_location->text(); + else + return QString::null; +} + +QString BookmarkEditDialog::finalTitle() const +{ + if (m_title!=0) + return m_title->text(); + else + return QString::null; +} + +extern "C" +{ + KDE_EXPORT KonqSidebarTreeModule* create_konq_sidebartree_bookmarks(KonqSidebarTree* par,const bool) + { + return new KonqSidebarBookmarkModule(par); + } +} + +#include "bookmark_module.moc" diff --git a/konqueror/sidebar/trees/bookmark_module/bookmark_module.h b/konqueror/sidebar/trees/bookmark_module/bookmark_module.h new file mode 100644 index 000000000..b38cdb540 --- /dev/null +++ b/konqueror/sidebar/trees/bookmark_module/bookmark_module.h @@ -0,0 +1,98 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef bookmark_module_h +#define bookmark_module_h + +#include <qmap.h> +#include <qobject.h> +#include <konq_sidebartreemodule.h> +#include <kbookmark.h> +#include <kdialogbase.h> +class KonqSidebarBookmarkItem; + +class KActionCollection; +class KLineEdit; + +/** + * This module displays bookmarks in the tree + */ +class KonqSidebarBookmarkModule : public QObject, public KonqSidebarTreeModule +{ + Q_OBJECT +public: + KonqSidebarBookmarkModule( KonqSidebarTree * parentTree ); + virtual ~KonqSidebarBookmarkModule(); + + // Handle this new toplevel item [can only be called once currently] + virtual void addTopLevelItem( KonqSidebarTreeTopLevelItem * item ); + virtual bool handleTopLevelContextMenu( KonqSidebarTreeTopLevelItem *, const QPoint& ); + + void showPopupMenu(); + + +protected slots: + void slotBookmarksChanged( const QString & ); + void slotMoved(QListViewItem*,QListViewItem*,QListViewItem*); + void slotDropped(KListView*,QDropEvent*,QListViewItem*,QListViewItem*); + void slotCreateFolder(); + void slotDelete(); + void slotProperties(KonqSidebarBookmarkItem *bi = 0); + void slotOpenNewWindow(); + void slotOpenTab(); + void slotCopyLocation(); + +protected: + void fillListView(); + void fillGroup( KonqSidebarTreeItem * parentItem, KBookmarkGroup group ); + KonqSidebarBookmarkItem * findByAddress( const QString & address ) const; + +private slots: + void slotOpenChange(QListViewItem*); + +private: + KonqSidebarTreeTopLevelItem * m_topLevelItem; + KonqSidebarBookmarkItem * m_rootItem; + + KActionCollection *m_collection; + + bool m_ignoreOpenChange; + QMap<QString, bool> m_folderOpenState; +}; + +class BookmarkEditDialog : public KDialogBase +{ + Q_OBJECT + +public: + BookmarkEditDialog( const QString& title, const QString& url, + QWidget * = 0, const char * = 0, + const QString& caption = i18n( "Add Bookmark" ) ); + + QString finalUrl() const; + QString finalTitle() const; + +protected slots: + void slotOk(); + void slotCancel(); + +private: + KLineEdit *m_title, *m_location; +}; + +#endif diff --git a/konqueror/sidebar/trees/dirtree_module/Makefile.am b/konqueror/sidebar/trees/dirtree_module/Makefile.am new file mode 100644 index 000000000..eb6cf061c --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/libkonq -I$(srcdir)/.. -I$(srcdir)/../.. $(all_includes) + +kde_module_LTLIBRARIES = konq_sidebartree_dirtree.la + +METASOURCES = AUTO +konq_sidebartree_dirtree_la_SOURCES = dirtree_module.cpp dirtree_item.cpp +konq_sidebartree_dirtree_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +konq_sidebartree_dirtree_la_LIBADD = ../../libkonqsidebarplugin.la ../libkonq_sidebar_tree.la + + diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp b/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp new file mode 100644 index 000000000..78132010a --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp @@ -0,0 +1,245 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +//#include "konq_treepart.h" +#include "dirtree_item.h" +#include "dirtree_module.h" +#include <konq_operations.h> +#include <konq_drag.h> +#include <kdebug.h> +#include <kglobalsettings.h> +#include <kuserprofile.h> +#include <qapplication.h> +#include <qclipboard.h> +#include <kio/paste.h> +#include <qfile.h> +#include <qpainter.h> +#include <kiconloader.h> +#include <qcursor.h> + +#define MYMODULE static_cast<KonqSidebarDirTreeModule*>(module()) + +KonqSidebarDirTreeItem::KonqSidebarDirTreeItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ) + : KonqSidebarTreeItem( parentItem, topLevelItem ), m_fileItem( fileItem ) +{ + if ( m_topLevelItem ) + MYMODULE->addSubDir( this ); + reset(); +} + +KonqSidebarDirTreeItem::KonqSidebarDirTreeItem( KonqSidebarTree *parent, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ) + : KonqSidebarTreeItem( parent, topLevelItem ), m_fileItem( fileItem ) +{ + if ( m_topLevelItem ) + MYMODULE->addSubDir( this ); + reset(); +} + +KonqSidebarDirTreeItem::~KonqSidebarDirTreeItem() +{ +} + +void KonqSidebarDirTreeItem::reset() +{ + bool expandable = true; + // For local dirs, find out if they have no children, to remove the "+" + if ( m_fileItem->isDir() ) + { + KURL url = m_fileItem->url(); + if ( url.isLocalFile() ) + { + QCString path( QFile::encodeName(url.path())); + struct stat buff; + if ( ::stat( path.data(), &buff ) != -1 ) + { + //kdDebug() << "KonqSidebarDirTreeItem::init " << path << " : " << buff.st_nlink << endl; + // The link count for a directory is generally subdir_count + 2. + // One exception is if there are hard links to the directory, in this case + // the link count can be > 2 even if no subdirs exist. + // The other exception are smb (and maybe netware) mounted directories + // of which the link count is always 1. Therefore, we only set the item + // as non-expandable if it's exactly 2 (one link from the parent dir, + // plus one from the '.' entry). + if ( buff.st_nlink == 2 ) + expandable = false; + } + } + } + setExpandable( expandable ); + id = m_fileItem->url().url(-1); +} + +void KonqSidebarDirTreeItem::setOpen( bool open ) +{ + kdDebug(1201) << "KonqSidebarDirTreeItem::setOpen " << open << endl; + if ( open && !childCount() && m_bListable ) + MYMODULE->openSubFolder( this ); + else if ( hasStandardIcon() ) + { + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + if ( open ) + setPixmap( 0, DesktopIcon( "folder_open", size ) ); + else + setPixmap( 0, m_fileItem->pixmap( size ) ); + } + KonqSidebarTreeItem::setOpen( open ); +} + +bool KonqSidebarDirTreeItem::hasStandardIcon() +{ + // The reason why we can't use KFileItem::iconName() is that it doesn't + // take custom icons in .directory files into account + return m_fileItem->determineMimeType()->icon( m_fileItem->url(), m_fileItem->isLocalFile() ) == "folder"; +} + +void KonqSidebarDirTreeItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + if (m_fileItem->isLink()) + { + QFont f( _painter->font() ); + f.setItalic( TRUE ); + _painter->setFont( f ); + } + QListViewItem::paintCell( _painter, _cg, _column, _width, _alignment ); +} + +KURL KonqSidebarDirTreeItem::externalURL() const +{ + return m_fileItem->url(); +} + +QString KonqSidebarDirTreeItem::externalMimeType() const +{ + if (m_fileItem->isMimeTypeKnown()) + return m_fileItem->mimetype(); + else + return QString::null; +} + +bool KonqSidebarDirTreeItem::acceptsDrops( const QStrList & formats ) +{ + if ( formats.contains("text/uri-list") ) + return m_fileItem->acceptsDrops(); + return false; +} + +void KonqSidebarDirTreeItem::drop( QDropEvent * ev ) +{ + KonqOperations::doDrop( m_fileItem, externalURL(), ev, tree() ); +} + +QDragObject * KonqSidebarDirTreeItem::dragObject( QWidget * parent, bool move ) +{ + KURL::List lst; + lst.append( m_fileItem->url() ); + + KonqDrag * drag = KonqDrag::newDrag( lst, false, parent ); + drag->setMoveSelection( move ); + + return drag; +} + +void KonqSidebarDirTreeItem::itemSelected() +{ + bool bInTrash = false; + + if ( m_fileItem->url().directory(false) == KGlobalSettings::trashPath() ) + bInTrash = true; + + QMimeSource *data = QApplication::clipboard()->data(); + bool paste = ( data->encodedData( data->format() ).size() != 0 ); + + tree()->enableActions( true, true, paste, true && !bInTrash, true, true ); +} + +void KonqSidebarDirTreeItem::middleButtonClicked() +{ + // Duplicated from KonqDirPart :( + // Optimisation to avoid KRun to call kfmclient that then tells us + // to open a window :-) + KService::Ptr offer = KServiceTypeProfile::preferredService(m_fileItem->mimetype(), "Application"); + if (offer) kdDebug(1201) << "KonqDirPart::mmbClicked: got service " << offer->desktopEntryName() << endl; + if ( offer && offer->desktopEntryName().startsWith("kfmclient") ) + { + kdDebug(1201)<<"Emitting createNewWindow"<<endl; + KParts::URLArgs args; + args.serviceType = m_fileItem->mimetype(); + emit tree()->createNewWindow( m_fileItem->url(), args ); + } + else + m_fileItem->run(); +} + +void KonqSidebarDirTreeItem::rightButtonPressed() +{ + KFileItemList lstItems; + lstItems.append( m_fileItem ); + emit tree()->popupMenu( QCursor::pos(), lstItems ); +} + +void KonqSidebarDirTreeItem::paste() +{ + // move or not move ? + bool move = false; + QMimeSource *data = QApplication::clipboard()->data(); + if ( data->provides( "application/x-kde-cutselection" ) ) { + move = KonqDrag::decodeIsCutSelection( data ); + kdDebug(1201) << "move (from clipboard data) = " << move << endl; + } + + KIO::pasteClipboard( m_fileItem->url(), move ); +} + +void KonqSidebarDirTreeItem::trash() +{ + delOperation( KonqOperations::TRASH ); +} + +void KonqSidebarDirTreeItem::del() +{ + delOperation( KonqOperations::DEL ); +} + +void KonqSidebarDirTreeItem::shred() +{ + delOperation( KonqOperations::SHRED ); +} + +void KonqSidebarDirTreeItem::delOperation( int method ) +{ + KURL::List lst; + lst.append(m_fileItem->url()); + + KonqOperations::del(tree(), method, lst); +} + +QString KonqSidebarDirTreeItem::toolTipText() const +{ + return m_fileItem->url().pathOrURL(); +} + +void KonqSidebarDirTreeItem::rename() +{ + tree()->rename( this, 0 ); +} + +void KonqSidebarDirTreeItem::rename( const QString & name ) +{ + KonqOperations::rename( tree(), m_fileItem->url(), name ); +} diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_item.h b/konqueror/sidebar/trees/dirtree_module/dirtree_item.h new file mode 100644 index 000000000..fe98595e6 --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_item.h @@ -0,0 +1,73 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef dirtree_item_h +#define dirtree_item_h + +#include "konq_sidebartreeitem.h" +#include <kurl.h> +#include <qstringlist.h> +class QDropEvent; +class KFileItem; + +class KonqSidebarDirTreeItem : public KonqSidebarTreeItem +{ +public: + KonqSidebarDirTreeItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ); + KonqSidebarDirTreeItem( KonqSidebarTree *parent, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ); + ~KonqSidebarDirTreeItem(); + + KFileItem *fileItem() const { return m_fileItem; } + + virtual void setOpen( bool open ); + + virtual void paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ); + + virtual bool acceptsDrops( const QStrList & formats ); + virtual void drop( QDropEvent * ev ); + virtual QDragObject * dragObject( QWidget * parent, bool move = false ); + + virtual void middleButtonClicked(); + virtual void rightButtonPressed(); + + virtual void paste(); + virtual void trash(); + virtual void del(); + virtual void shred(); + virtual void rename(); // start a rename operation + void rename( const QString & name ); // do the actual renaming + + // The URL to open when this link is clicked + virtual KURL externalURL() const; + virtual QString externalMimeType() const; + virtual QString toolTipText() const; + + virtual void itemSelected(); + + void reset(); + + bool hasStandardIcon(); + + QString id; + +private: + void delOperation( int method ); + KFileItem *m_fileItem; +}; + +#endif diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp b/konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp new file mode 100644 index 000000000..725927362 --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp @@ -0,0 +1,649 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + 2002 Michael Brade <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "dirtree_module.h" +#include "dirtree_item.h" +#include <kdebug.h> +#include <kprotocolinfo.h> +#include <kdesktopfile.h> +#include <kmessagebox.h> +#include <kiconloader.h> +#include <kdirlister.h> +#include "konqsidebariface_p.h" + + +KonqSidebarDirTreeModule::KonqSidebarDirTreeModule( KonqSidebarTree * parentTree , bool showHidden) + : KonqSidebarTreeModule( parentTree, showHidden ), m_dirLister(0L), m_topLevelItem(0L) +{ + bool universalMode=false; + /* Doesn't work reliable :-( + + KonqSidebarPlugin * plugin = parentTree->part(); + // KonqSidebarPlugin::universalMode() is protected :-| + if ( plugin->parent() ) { + KonqSidebarIface * ksi = static_cast<KonqSidebarIface*>( plugin->parent()->qt_cast( "KonqSidebarIface" ) ); + universalMode = ksi ? ksi->universalMode() : false; + } */ + + KConfig * config = new KConfig( universalMode ? "konqsidebartng_kicker.rc" : "konqsidebartng.rc" ); + config->setGroup(""); + m_showArchivesAsFolders = config->readBoolEntry("ShowArchivesAsFolders",true); + delete config; +} + +KonqSidebarDirTreeModule::~KonqSidebarDirTreeModule() +{ + // KDirLister may still emit canceled while being deleted. + if (m_dirLister) + { + disconnect( m_dirLister, SIGNAL( canceled( const KURL & ) ), + this, SLOT( slotListingStopped( const KURL & ) ) ); + delete m_dirLister; + } +} + +KURL::List KonqSidebarDirTreeModule::selectedUrls() +{ + KURL::List lst; + KonqSidebarDirTreeItem *selection = static_cast<KonqSidebarDirTreeItem *>( m_pTree->selectedItem() ); + if( !selection ) + { + kdError() << "KonqSidebarDirTreeModule::selectedUrls: no selection!" << endl; + return lst; + } + lst.append(selection->fileItem()->url()); + return lst; +} + +void KonqSidebarDirTreeModule::addTopLevelItem( KonqSidebarTreeTopLevelItem * item ) +{ + if(m_topLevelItem) // We can handle only one at a time ! + kdError() << "KonqSidebarDirTreeModule::addTopLevelItem: Impossible, we can have only one toplevel item !" << endl; + + KDesktopFile cfg( item->path(), true ); + cfg.setDollarExpansion(true); + + KURL targetURL; + targetURL.setPath(item->path()); + + if ( cfg.hasLinkType() ) + { + targetURL = cfg.readURL(); + // some services might want to make their URL configurable in kcontrol + QString configured = cfg.readEntry("X-KDE-ConfiguredURL"); + if (!configured.isEmpty()) { + QStringList list = QStringList::split(':', configured); + KConfig config(list[0]); + if (list[1] != "noGroup") config.setGroup(list[1]); + QString conf_url = config.readEntry(list[2]); + if (!conf_url.isEmpty()) { + targetURL = conf_url; + } + } + } + else if ( cfg.hasDeviceType() ) + { + // Determine the mountpoint + QString mp = cfg.readEntry("MountPoint"); + if ( mp.isEmpty() ) + return; + + targetURL.setPath(mp); + } + else + return; + + bool bListable = KProtocolInfo::supportsListing( targetURL ); + //kdDebug(1201) << targetURL.prettyURL() << " listable : " << bListable << endl; + + if ( !bListable ) + { + item->setExpandable( false ); + item->setListable( false ); + } + + item->setExternalURL( targetURL ); + addSubDir( item ); + + m_topLevelItem = item; +} + +void KonqSidebarDirTreeModule::openTopLevelItem( KonqSidebarTreeTopLevelItem * item ) +{ + if ( !item->childCount() && item->isListable() ) + openSubFolder( item ); +} + +void KonqSidebarDirTreeModule::addSubDir( KonqSidebarTreeItem *item ) +{ + QString id = item->externalURL().url(-1); + kdDebug(1201) << this << " KonqSidebarDirTreeModule::addSubDir " << id << endl; + m_dictSubDirs.insert(id, item ); + + KonqSidebarDirTreeItem *ditem = dynamic_cast<KonqSidebarDirTreeItem*>(item); + if (ditem) + m_ptrdictSubDirs.insert(ditem->fileItem(), item); +} + +// Remove <key, item> from dict, taking into account that there maybe +// other items with the same key. +static void remove(QDict<KonqSidebarTreeItem> &dict, const QString &key, KonqSidebarTreeItem *item) +{ + QPtrList<KonqSidebarTreeItem> *otherItems = 0; + while(true) { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem || (takeItem == item)) + { + if (!otherItems) + return; + + // Insert the otherItems back in + for(KonqSidebarTreeItem *otherItem; (otherItem = otherItems->take(0));) + { + dict.insert(key, otherItem); + } + delete otherItems; + return; + } + // Not the item we are looking for + if (!otherItems) + otherItems = new QPtrList<KonqSidebarTreeItem>(); + + otherItems->prepend(takeItem); + } +} + +// Looks up key in dict and returns it in item, if there are multiple items +// with the same key, additional items are returned in itemList which should +// be deleted by the caller. +static void lookupItems(QDict<KonqSidebarTreeItem> &dict, const QString &key, KonqSidebarTreeItem *&item, QPtrList<KonqSidebarTreeItem> *&itemList) +{ + itemList = 0; + item = dict.take(key); + if (!item) + return; + + while(true) + { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem) + { + // + // Insert itemList back in + if (itemList) + { + for(KonqSidebarTreeItem *otherItem = itemList->first(); otherItem; otherItem = itemList->next()) + dict.insert(key, otherItem); + } + dict.insert(key, item); + return; + } + if (!itemList) + itemList = new QPtrList<KonqSidebarTreeItem>(); + + itemList->prepend(takeItem); + } +} + +// Remove <key, item> from dict, taking into account that there maybe +// other items with the same key. +static void remove(QPtrDict<KonqSidebarTreeItem> &dict, void *key, KonqSidebarTreeItem *item) +{ + QPtrList<KonqSidebarTreeItem> *otherItems = 0; + while(true) { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem || (takeItem == item)) + { + if (!otherItems) + return; + + // Insert the otherItems back in + for(KonqSidebarTreeItem *otherItem; (otherItem = otherItems->take(0));) + { + dict.insert(key, otherItem); + } + delete otherItems; + return; + } + // Not the item we are looking for + if (!otherItems) + otherItems = new QPtrList<KonqSidebarTreeItem>(); + + otherItems->prepend(takeItem); + } +} + +// Looks up key in dict and returns it in item, if there are multiple items +// with the same key, additional items are returned in itemList which should +// be deleted by the caller. +static void lookupItems(QPtrDict<KonqSidebarTreeItem> &dict, void *key, KonqSidebarTreeItem *&item, QPtrList<KonqSidebarTreeItem> *&itemList) +{ + itemList = 0; + item = dict.take(key); + if (!item) + return; + + while(true) + { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem) + { + // + // Insert itemList back in + if (itemList) + { + for(KonqSidebarTreeItem *otherItem = itemList->first(); otherItem; otherItem = itemList->next()) + dict.insert(key, otherItem); + } + dict.insert(key, item); + return; + } + if (!itemList) + itemList = new QPtrList<KonqSidebarTreeItem>(); + + itemList->prepend(takeItem); + } +} + + +void KonqSidebarDirTreeModule::removeSubDir( KonqSidebarTreeItem *item, bool childrenOnly ) +{ + kdDebug(1201) << this << " KonqSidebarDirTreeModule::removeSubDir item=" << item << endl; + if ( item->firstChild() ) + { + KonqSidebarTreeItem * it = static_cast<KonqSidebarTreeItem *>(item->firstChild()); + KonqSidebarTreeItem * next = 0L; + while ( it ) { + next = static_cast<KonqSidebarTreeItem *>(it->nextSibling()); + removeSubDir( it ); + delete it; + it = next; + } + } + + if ( !childrenOnly ) + { + QString id = item->externalURL().url(-1); + remove(m_dictSubDirs, id, item); + while (!(item->alias.isEmpty())) + { + remove(m_dictSubDirs, item->alias.front(), item); + item->alias.pop_front(); + } + + KonqSidebarDirTreeItem *ditem = dynamic_cast<KonqSidebarDirTreeItem*>(item); + if (ditem) + remove(m_ptrdictSubDirs, ditem->fileItem(), item); + } +} + + +void KonqSidebarDirTreeModule::openSubFolder( KonqSidebarTreeItem *item ) +{ + kdDebug(1201) << this << " openSubFolder( " << item->externalURL().prettyURL() << " )" << endl; + + if ( !m_dirLister ) // created on demand + { + m_dirLister = new KDirLister( true ); + //m_dirLister->setDirOnlyMode( true ); +// QStringList mimetypes; +// mimetypes<<QString("inode/directory"); +// m_dirLister->setMimeFilter(mimetypes); + + connect( m_dirLister, SIGNAL( newItems( const KFileItemList & ) ), + this, SLOT( slotNewItems( const KFileItemList & ) ) ); + connect( m_dirLister, SIGNAL( refreshItems( const KFileItemList & ) ), + this, SLOT( slotRefreshItems( const KFileItemList & ) ) ); + connect( m_dirLister, SIGNAL( deleteItem( KFileItem * ) ), + this, SLOT( slotDeleteItem( KFileItem * ) ) ); + connect( m_dirLister, SIGNAL( completed( const KURL & ) ), + this, SLOT( slotListingStopped( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( canceled( const KURL & ) ), + this, SLOT( slotListingStopped( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( redirection( const KURL &, const KURL & ) ), + this, SLOT( slotRedirection( const KURL &, const KURL & ) ) ); + } + + + if ( !item->isTopLevelItem() && + static_cast<KonqSidebarDirTreeItem *>(item)->hasStandardIcon() ) + { + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + QPixmap pix = DesktopIcon( "folder_open", size ); + m_pTree->startAnimation( item, "kde", 6, &pix ); + } + else + m_pTree->startAnimation( item ); + + listDirectory( item ); +} + +void KonqSidebarDirTreeModule::listDirectory( KonqSidebarTreeItem *item ) +{ + // This causes a reparsing, but gets rid of the trailing slash + QString strUrl = item->externalURL().url(-1); + KURL url( strUrl ); + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * openItem; + lookupItems(m_dictSubDirs, strUrl, openItem, itemList); + + while(openItem) + { + if (openItem->childCount()) + break; + + openItem = itemList ? itemList->take(0) : 0; + } + delete itemList; + + if (openItem) + { + // We have this directory listed already, just copy the entries as we + // can't use the dirlister, it would invalidate the old entries + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + KonqSidebarTreeItem * parentItem = item; + KonqSidebarDirTreeItem *oldItem = static_cast<KonqSidebarDirTreeItem *> (openItem->firstChild()); + while(oldItem) + { + KFileItem * fileItem = oldItem->fileItem(); + if (! fileItem->isDir() ) + { + KMimeType::Ptr ptr; + + if ( fileItem->url().isLocalFile() && (((ptr=fileItem->determineMimeType())!=0) && (ptr->is("inode/directory") || m_showArchivesAsFolders) && ((!ptr->property("X-KDE-LocalProtocol").toString().isEmpty()) ))) { + kdDebug()<<"Something not really a directory"<<endl; + } else { +// kdError() << "Item " << fileItem->url().prettyURL() << " is not a directory!" << endl; + continue; + } + } + + KonqSidebarDirTreeItem *dirTreeItem = new KonqSidebarDirTreeItem( parentItem, m_topLevelItem, fileItem ); + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + + oldItem = static_cast<KonqSidebarDirTreeItem *> (oldItem->nextSibling()); + } + m_pTree->stopAnimation( item ); + + return; + } + + m_dirLister->setShowingDotFiles( showHidden()); + + if (tree()->isOpeningFirstChild()) m_dirLister->setAutoErrorHandlingEnabled(false,0); + else m_dirLister->setAutoErrorHandlingEnabled(true,tree()); + + m_dirLister->openURL( url, true /*keep*/ ); +} + +void KonqSidebarDirTreeModule::slotNewItems( const KFileItemList& entries ) +{ + kdDebug(1201) << this << " KonqSidebarDirTreeModule::slotNewItems " << entries.count() << endl; + + Q_ASSERT(entries.count()); + KFileItem * firstItem = const_cast<KFileItemList&>(entries).first(); // qlist sucks for constness + + // Find parent item - it's the same for all the items + KURL dir( firstItem->url().url(-1) ); + dir.setFileName( "" ); + kdDebug(1201) << this << " KonqSidebarDirTreeModule::slotNewItems dir=" << dir.url(-1) << endl; + + QPtrList<KonqSidebarTreeItem> *parentItemList; + KonqSidebarTreeItem * parentItem; + lookupItems(m_dictSubDirs, dir.url(-1), parentItem, parentItemList); + + if ( !parentItem ) // hack for dnssd://domain/type/service listed in dnssd:/type/ dir + { + dir.setHost( QString::null ); + lookupItems( m_dictSubDirs, dir.url(-1), parentItem, parentItemList ); + } + + if( !parentItem ) + { + KMessageBox::error( tree(), i18n("Cannot find parent item %1 in the tree. Internal error.").arg( dir.url(-1) ) ); + return; + } + + kdDebug()<<"number of additional parent items:"<< (parentItemList?parentItemList->count():0)<<endl; + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + do + { + kdDebug()<<"Parent Item URL:"<<parentItem->externalURL()<<endl; + QPtrListIterator<KFileItem> kit ( entries ); + for( ; kit.current(); ++kit ) + { + KFileItem * fileItem = *kit; + + if (! fileItem->isDir() ) + { + KMimeType::Ptr ptr; + + if ( fileItem->url().isLocalFile() && (( (ptr=fileItem->determineMimeType())!=0) && (ptr->is("inode/directory") || m_showArchivesAsFolders) && ((!ptr->property("X-KDE-LocalProtocol").toString().isEmpty()) ))) { + kdDebug()<<"Something really a directory"<<endl; + } else { + //kdError() << "Item " << fileItem->url().prettyURL() << " is not a directory!" << endl; + continue; + } + } + + KonqSidebarDirTreeItem *dirTreeItem = new KonqSidebarDirTreeItem( parentItem, m_topLevelItem, fileItem ); + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + } + + } while ((parentItem = parentItemList ? parentItemList->take(0) : 0)); + delete parentItemList; +} + +void KonqSidebarDirTreeModule::slotRefreshItems( const KFileItemList &entries ) +{ + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + + QPtrListIterator<KFileItem> kit ( entries ); + kdDebug(1201) << "KonqSidebarDirTreeModule::slotRefreshItems " << entries.count() << " entries. First: " << kit.current()->url().url() << endl; + for( ; kit.current(); ++kit ) + { + KFileItem *fileItem = kit.current(); + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_ptrdictSubDirs, fileItem, item, itemList); + + if (!item) + { + if ( fileItem->isDir() ) // don't warn for files + kdWarning(1201) << "KonqSidebarDirTreeModule::slotRefreshItems can't find old entry for " << kit.current()->url().url(-1) << endl; + continue; + } + + do + { + if ( item->isTopLevelItem() ) // we only have dirs and one toplevel item in the dict + { + kdWarning(1201) << "KonqSidebarDirTreeModule::slotRefreshItems entry for " << kit.current()->url().url(-1) << " matches against toplevel." << endl; + break; + } + + KonqSidebarDirTreeItem * dirTreeItem = static_cast<KonqSidebarDirTreeItem *>(item); + // Item renamed ? + if ( dirTreeItem->id != fileItem->url().url( -1 ) ) + { + // We need to update the URL in m_dictSubDirs, and to get rid of the child items, so remove and add. + // Then remove + delete + removeSubDir( dirTreeItem, true /*children only*/ ); + remove(m_dictSubDirs, dirTreeItem->id, dirTreeItem); + + dirTreeItem->reset(); // Reset id + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + + // Make sure the item doesn't get inserted twice! + // dirTreeItem->id points to the new name + remove(m_dictSubDirs, dirTreeItem->id, dirTreeItem); + m_dictSubDirs.insert(dirTreeItem->id, dirTreeItem); + } + else + { + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + } + + } while ((item = itemList ? itemList->take(0) : 0)); + delete itemList; + } +} + +void KonqSidebarDirTreeModule::slotDeleteItem( KFileItem *fileItem ) +{ + kdDebug(1201) << "KonqSidebarDirTreeModule::slotDeleteItem( " << fileItem->url().url(-1) << " )" << endl; + + // All items are in m_ptrdictSubDirs, so look it up fast + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_ptrdictSubDirs, fileItem, item, itemList); + while(item) + { + removeSubDir( item ); + delete item; + + item = itemList ? itemList->take(0) : 0; + } + delete itemList; +} + +void KonqSidebarDirTreeModule::slotRedirection( const KURL & oldUrl, const KURL & newUrl ) +{ + kdDebug(1201) << "******************************KonqSidebarDirTreeModule::slotRedirection(" << newUrl.prettyURL() << ")" << endl; + + QString oldUrlStr = oldUrl.url(-1); + QString newUrlStr = newUrl.url(-1); + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_dictSubDirs, oldUrlStr, item, itemList); + + if (!item) + { + kdWarning(1201) << "NOT FOUND oldUrl=" << oldUrlStr << endl; + return; + } + + do + { + if (item->alias.contains(newUrlStr)) continue; + kdDebug()<<"Redirectiong element"<<endl; + // We need to update the URL in m_dictSubDirs + m_dictSubDirs.insert( newUrlStr, item ); + item->alias << newUrlStr; + + kdDebug(1201) << "Updating url of " << item << " to " << newUrlStr << endl; + + } while ((item = itemList ? itemList->take(0) : 0)); + delete itemList; +} + +void KonqSidebarDirTreeModule::slotListingStopped( const KURL & url ) +{ + kdDebug(1201) << "KonqSidebarDirTree::slotListingStopped " << url.url(-1) << endl; + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_dictSubDirs, url.url(-1), item, itemList); + + while(item) + { + if ( item->childCount() == 0 ) + { + item->setExpandable( false ); + item->repaint(); + } + m_pTree->stopAnimation( item ); + + item = itemList ? itemList->take(0) : 0; + } + delete itemList; + + kdDebug(1201) << "m_selectAfterOpening " << m_selectAfterOpening.prettyURL() << endl; + if ( !m_selectAfterOpening.isEmpty() && url.isParentOf( m_selectAfterOpening ) ) + { + KURL theURL( m_selectAfterOpening ); + m_selectAfterOpening = KURL(); + followURL( theURL ); + } +} + +void KonqSidebarDirTreeModule::followURL( const KURL & url ) +{ + // Check if we already know this URL + KonqSidebarTreeItem * item = m_dictSubDirs[ url.url(-1) ]; + if (item) // found it -> ensure visible, select, return. + { + m_pTree->ensureItemVisible( item ); + m_pTree->setSelected( item, true ); + return; + } + + KURL uParent( url ); + KonqSidebarTreeItem * parentItem = 0L; + // Go up to the first known parent + do + { + uParent = uParent.upURL(); + parentItem = m_dictSubDirs[ uParent.url(-1) ]; + } while ( !parentItem && !uParent.path().isEmpty() && uParent.path() != "/" ); + + // Not found !?! + if (!parentItem) + { + kdDebug() << "No parent found for url " << url.prettyURL() << endl; + return; + } + kdDebug(1202) << "Found parent " << uParent.prettyURL() << endl; + + // That's the parent directory we found. Open if not open... + if ( !parentItem->isOpen() ) + { + parentItem->setOpen( true ); + if ( parentItem->childCount() && m_dictSubDirs[ url.url(-1) ] ) + { + // Immediate opening, if the dir was already listed + followURL( url ); // equivalent to a goto-beginning-of-method + } else + { + m_selectAfterOpening = url; + kdDebug(1202) << "KonqSidebarDirTreeModule::followURL: m_selectAfterOpening=" << m_selectAfterOpening.url() << endl; + } + } +} + + +extern "C" +{ + KDE_EXPORT KonqSidebarTreeModule *create_konq_sidebartree_dirtree(KonqSidebarTree* par,const bool showHidden) + { + return new KonqSidebarDirTreeModule(par,showHidden); + } +} + + + +#include "dirtree_module.moc" diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_module.h b/konqueror/sidebar/trees/dirtree_module/dirtree_module.h new file mode 100644 index 000000000..dc46d3b9e --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_module.h @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef dirtree_module_h +#define dirtree_module_h + +#include <konq_sidebartreemodule.h> +#include <kfileitem.h> +#include <qpixmap.h> +#include <qdict.h> +#include <qptrdict.h> + +class KDirLister; +class KonqSidebarTree; +class KonqSidebarTreeItem; +class KonqSidebarDirTreeItem; +class KonqPropsView; + +class KonqSidebarDirTreeModule : public QObject, public KonqSidebarTreeModule +{ + Q_OBJECT +public: + KonqSidebarDirTreeModule( KonqSidebarTree * parentTree, bool ); + virtual ~KonqSidebarDirTreeModule(); + + virtual void addTopLevelItem( KonqSidebarTreeTopLevelItem * item ); + + virtual void openTopLevelItem( KonqSidebarTreeTopLevelItem * item ); + + virtual void followURL( const KURL & url ); + + // Called by KonqSidebarDirTreeItem + void openSubFolder( KonqSidebarTreeItem *item ); + void addSubDir( KonqSidebarTreeItem *item ); + void removeSubDir( KonqSidebarTreeItem *item, bool childrenonly = false ); + +private slots: + void slotNewItems( const KFileItemList & ); + void slotRefreshItems( const KFileItemList & ); + void slotDeleteItem( KFileItem *item ); + void slotRedirection( const KURL & oldUrl, const KURL & newUrl ); + void slotListingStopped( const KURL & url ); + +private: + //KonqSidebarTreeItem * findDir( const KURL &_url ); + void listDirectory( KonqSidebarTreeItem *item ); + KURL::List selectedUrls(); + + // URL -> item + // Each KonqSidebarDirTreeItem is indexed on item->id() and + // all item->alias'es + QDict<KonqSidebarTreeItem> m_dictSubDirs; + + // KFileItem -> item + QPtrDict<KonqSidebarTreeItem> m_ptrdictSubDirs; + + KDirLister * m_dirLister; + + KURL m_selectAfterOpening; + + KonqSidebarTreeTopLevelItem * m_topLevelItem; + + bool m_showArchivesAsFolders; +}; + + +#endif diff --git a/konqueror/sidebar/trees/history_module/Makefile.am b/konqueror/sidebar/trees/history_module/Makefile.am new file mode 100644 index 000000000..5f033d662 --- /dev/null +++ b/konqueror/sidebar/trees/history_module/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I$(top_srcdir)/libkonq -I$(srcdir)/.. -I$(srcdir)/../.. $(all_includes) + +kde_module_LTLIBRARIES = konq_sidebartree_history.la kcm_history.la + +METASOURCES = AUTO + +konq_sidebartree_history_la_SOURCES = history_module.cpp history_item.cpp \ + history_settings.cpp history_settings.skel +konq_sidebartree_history_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +konq_sidebartree_history_la_LIBADD = ../../libkonqsidebarplugin.la ../libkonq_sidebar_tree.la + +kcm_history_la_SOURCES = kcmhistory.cpp history_dlg.ui history_settings.cpp history_settings.skel +kcm_history_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +kcm_history_la_LIBADD = -lkdeui $(top_builddir)/libkonq/libkonq.la + +xdg_apps_DATA = kcmhistory.desktop diff --git a/konqueror/sidebar/trees/history_module/history_dlg.ui b/konqueror/sidebar/trees/history_module/history_dlg.ui new file mode 100644 index 000000000..32fd31296 --- /dev/null +++ b/konqueror/sidebar/trees/history_module/history_dlg.ui @@ -0,0 +1,239 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KonqSidebarHistoryDlg</class> +<widget class="QWidget"> + <property name="name"> + <cstring>KonqHistoryDlg</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>450</width> + <height>290</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>gbLimits</cstring> + </property> + <property name="title"> + <string>Limits</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="2"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>240</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>cbExpire</cstring> + </property> + <property name="text"> + <string>URLs e&xpire after</string> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>spinExpire</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>lEntries</cstring> + </property> + <property name="text"> + <string>Maximum &number of URLs:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spinEntries</cstring> + </property> + </widget> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>spinEntries</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>gbFonts</cstring> + </property> + <property name="title"> + <string>Custom Fonts For</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>spinNewer</cstring> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>spinOlder</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="2"> + <property name="name"> + <cstring>comboOlder</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>lbNewer</cstring> + </property> + <property name="text"> + <string>URLs newer than</string> + </property> + </widget> + <widget class="QComboBox" row="0" column="2"> + <property name="name"> + <cstring>comboNewer</cstring> + </property> + </widget> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>btnFontOlder</cstring> + </property> + <property name="text"> + <string>Choose Font...</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>lbOlder</cstring> + </property> + <property name="text"> + <string>URLs older than</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="3"> + <property name="name"> + <cstring>btnFontNewer</cstring> + </property> + <property name="text"> + <string>Choose Font...</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>gbDetails</cstring> + </property> + <property name="title"> + <string>Details</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>cbDetailedTips</cstring> + </property> + <property name="text"> + <string>Detailed tooltips</string> + </property> + <property name="toolTip" stdset="0"> + <string>Shows the number of times visited and the dates of the first and last visits, in addition to the URL</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnClearHistory</cstring> + </property> + <property name="text"> + <string>Clear History</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>418</width> + <height>0</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>30</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="0"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/konqueror/sidebar/trees/history_module/history_item.cpp b/konqueror/sidebar/trees/history_module/history_item.cpp new file mode 100644 index 000000000..bfda3152c --- /dev/null +++ b/konqueror/sidebar/trees/history_module/history_item.cpp @@ -0,0 +1,246 @@ +/* This file is part of the KDE project + Copyright (C) 2000,2001 Carsten Pfeiffer <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <kbookmarkdrag.h> +#include <kprotocolinfo.h> +#include <konq_faviconmgr.h> +#include <qpainter.h> + +#include <assert.h> + +#include "history_item.h" +#include "history_module.h" +#include "history_settings.h" +#include <kiconloader.h> + +#define MYMODULE static_cast<KonqSidebarHistoryModule*>(module()) +#define MYGROUP static_cast<KonqSidebarHistoryGroupItem*>(parent()) + +KonqSidebarHistorySettings * KonqSidebarHistoryItem::s_settings = 0L; + +KonqSidebarHistoryItem::KonqSidebarHistoryItem( const KonqHistoryEntry *entry, + KonqSidebarTreeItem * parentItem, + KonqSidebarTreeTopLevelItem *topLevelItem ) + : KonqSidebarTreeItem( parentItem, topLevelItem ) +{ + setExpandable( false ); + update( entry ); +} + +KonqSidebarHistoryItem::~KonqSidebarHistoryItem() +{ +} + +void KonqSidebarHistoryItem::update( const KonqHistoryEntry *entry ) +{ + m_entry = entry; + + if (!entry) + return; + + QString title( entry->title ); + if ( !title.stripWhiteSpace().isEmpty() && + title != entry->url.url() ) + setText( 0, title ); + else { + QString path( entry->url.path() ); + if ( path.isEmpty() ) + path += '/'; + setText( 0, path ); + } + + KonqSidebarHistoryGroupItem *group = MYGROUP; + assert(group); + QString path = entry->url.path(); + if ( group->hasFavIcon() && (path.isNull() || path == "/") ) + { + const QPixmap *pm = group->pixmap(0); + if (pm) + setPixmap( 0, *pm ); + } + else + { + setPixmap( 0, SmallIcon(KProtocolInfo::icon( entry->url.protocol() ))); + } + + group->itemUpdated( this ); // update for sorting +} + +void KonqSidebarHistoryItem::itemSelected() +{ + tree()->enableActions( true, true, false, false, false, false ); +} + +void KonqSidebarHistoryItem::rightButtonPressed() +{ + MYMODULE->showPopupMenu(); +} + +QDragObject * KonqSidebarHistoryItem::dragObject( QWidget * parent, bool /*move*/ ) +{ + QString icon = KonqFavIconMgr::iconForURL( m_entry->url.url() ); + KBookmark bookmark = KBookmark::standaloneBookmark( m_entry->title, + m_entry->url, icon ); + KBookmarkDrag *drag = KBookmarkDrag::newDrag( bookmark, parent ); + return drag; +} + +// new items go on top +QString KonqSidebarHistoryItem::key( int column, bool ascending ) const +{ + if ( MYMODULE->sortsByName() ) + return KonqSidebarTreeItem::key( column, ascending ); + + QString tmp; + tmp.sprintf( "%08x", m_entry->lastVisited.secsTo(MYMODULE->currentTime())); + return tmp; +} + +QString KonqSidebarHistoryItem::toolTipText() const +{ + if ( s_settings->m_detailedTips ) { + // this weird ordering of %4, %1, %2, %3 is due to the reason, that some + // urls seem to contain %N, which would get substituted in the next + // .arg() calls. So to fix this, we first substitute the last items + // and then put in the url. + QString tip = i18n("<qt><center><b>%4</b></center><hr>Last visited: %1<br>First visited: %2<br>Number of times visited: %3</qt>"); + return tip.arg( KGlobal::locale()->formatDateTime( m_entry->lastVisited ) ).arg( KGlobal::locale()->formatDateTime( m_entry->firstVisited ) ).arg( m_entry->numberOfTimesVisited ).arg( m_entry->url.url() ); + } + + return m_entry->url.url(); +} + +void KonqSidebarHistoryItem::paintCell( QPainter *p, const QColorGroup & cg, + int column, int width, int alignment ) +{ + QDateTime dt; + QDateTime current = QDateTime::currentDateTime(); + + if ( s_settings->m_metricYoungerThan == KonqSidebarHistorySettings::DAYS ) + dt = current.addDays( - s_settings->m_valueYoungerThan ); + else + dt = current.addSecs( - (s_settings->m_valueYoungerThan * 60) ); + + if ( m_entry->lastVisited > dt ) + p->setFont( s_settings->m_fontYoungerThan ); + + else { + if ( s_settings->m_metricOlderThan == KonqSidebarHistorySettings::DAYS ) + dt = current.addDays( - s_settings->m_valueOlderThan ); + else + dt = current.addSecs( - (s_settings->m_valueOlderThan * 60) ); + + if ( m_entry->lastVisited < dt ) + p->setFont( s_settings->m_fontOlderThan ); + } + + KonqSidebarTreeItem::paintCell( p, cg, column, width, alignment ); +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + +KonqSidebarHistoryGroupItem::KonqSidebarHistoryGroupItem( const KURL& url, + KonqSidebarTreeTopLevelItem *topLevelItem) + : KonqSidebarTreeItem( topLevelItem, topLevelItem ), + m_hasFavIcon( false ), + m_url( url ) +{ +} + +void KonqSidebarHistoryGroupItem::setFavIcon( const QPixmap& pix ) +{ + setPixmap( 0, pix ); + m_hasFavIcon = true; +} + +// the group item itself will be removed automatically, +// when the last child is removed +void KonqSidebarHistoryGroupItem::remove() +{ + KURL::List list; + KonqSidebarHistoryItem *child = static_cast<KonqSidebarHistoryItem*>( firstChild() ); + while( child ) { + list.append( child->externalURL() ); + child = static_cast<KonqSidebarHistoryItem*>( child->nextSibling() ); + } + + if ( !list.isEmpty() ) + KonqHistoryManager::kself()->emitRemoveFromHistory( list ); +} + +KonqSidebarHistoryItem * KonqSidebarHistoryGroupItem::findChild(const KonqHistoryEntry *entry) const +{ + QListViewItem *child = firstChild(); + KonqSidebarHistoryItem *item = 0L; + + while ( child ) { + item = static_cast<KonqSidebarHistoryItem *>( child ); + if ( item->entry() == entry ) + return item; + + child = child->nextSibling(); + } + + return 0L; +} + +void KonqSidebarHistoryGroupItem::itemSelected() +{ + tree()->enableActions( false, false, false, + false, false, false ); +} + +void KonqSidebarHistoryGroupItem::rightButtonPressed() +{ + MYMODULE->showPopupMenu(); +} + +// let the module change our pixmap (opened/closed) +void KonqSidebarHistoryGroupItem::setOpen( bool open ) +{ + MYMODULE->groupOpened( this, open ); + KonqSidebarTreeItem::setOpen( open ); +} + +// new items go on top +QString KonqSidebarHistoryGroupItem::key( int column, bool ascending ) const +{ + if ( !m_lastVisited.isValid() || MYMODULE->sortsByName() ) + return KonqSidebarTreeItem::key( column, ascending ); + + QString tmp; + tmp.sprintf( "%08x", m_lastVisited.secsTo( MYMODULE->currentTime() )); + return tmp; +} + +void KonqSidebarHistoryGroupItem::itemUpdated( KonqSidebarHistoryItem *item ) +{ + if ( !m_lastVisited.isValid() || m_lastVisited < item->lastVisited() ) + m_lastVisited = item->lastVisited(); +} + +QDragObject * KonqSidebarHistoryGroupItem::dragObject( QWidget *parent, bool /*move*/) +{ + QString icon = KonqFavIconMgr::iconForURL( m_url.url() ); + KBookmark bookmark = KBookmark::standaloneBookmark( QString::null, m_url, + icon ); + KBookmarkDrag *drag = KBookmarkDrag::newDrag( bookmark, parent ); + return drag; +} diff --git a/konqueror/sidebar/trees/history_module/history_item.h b/konqueror/sidebar/trees/history_module/history_item.h new file mode 100644 index 000000000..a7c77a677 --- /dev/null +++ b/konqueror/sidebar/trees/history_module/history_item.h @@ -0,0 +1,111 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Carsten Pfeiffer <[email protected] + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HISTORY_ITEM_H +#define HISTORY_ITEM_H + +#include <kurl.h> +#include <konq_historymgr.h> + +#include "konq_sidebartreeitem.h" + +class QDropEvent; +class QPainter; +class KonqSidebarHistorySettings; + +class KonqSidebarHistoryItem : public KonqSidebarTreeItem +{ +public: + KonqSidebarHistoryItem( const KonqHistoryEntry *entry, + KonqSidebarTreeItem *parentItem, + KonqSidebarTreeTopLevelItem *topLevelItem ); + ~KonqSidebarHistoryItem(); + + virtual void rightButtonPressed(); + + virtual void itemSelected(); + + // The URL to open when this link is clicked + virtual KURL externalURL() const { return m_entry->url; } + const KURL& url() const { return m_entry->url; } // a faster one + virtual QString toolTipText() const; + + QString host() const { return m_entry->url.host(); } + QString path() const { return m_entry->url.path(); } + + const QDateTime& lastVisited() const { return m_entry->lastVisited; } + + void update( const KonqHistoryEntry *entry ); + const KonqHistoryEntry *entry() const { return m_entry; } + + virtual QDragObject * dragObject( QWidget * parent, bool move = false ); + + virtual QString key( int column, bool ascending ) const; + + static void setSettings( KonqSidebarHistorySettings *s ) { s_settings = s; } + + virtual void paintCell( QPainter *, const QColorGroup & cg, int column, + int width, int alignment ); + +private: + const KonqHistoryEntry *m_entry; + static KonqSidebarHistorySettings *s_settings; + +}; + +class KonqSidebarHistoryGroupItem : public KonqSidebarTreeItem +{ +public: + + KonqSidebarHistoryGroupItem( const KURL& url, KonqSidebarTreeTopLevelItem * ); + + /** + * removes itself and all its children from the history (not just the view) + */ + void remove(); + + KonqSidebarHistoryItem * findChild( const KonqHistoryEntry *entry ) const; + + virtual void rightButtonPressed(); + + virtual void setOpen( bool open ); + + virtual QString key( int column, bool ascending ) const; + + void itemUpdated( KonqSidebarHistoryItem *item ); + + bool hasFavIcon() const { return m_hasFavIcon; } + void setFavIcon( const QPixmap& pix ); + + virtual QDragObject * dragObject( QWidget *, bool ); + virtual void itemSelected(); + + // we don't support the following of KonqSidebarTreeItem + bool acceptsDrops( const QStrList& ) { return false; } + virtual void drop( QDropEvent * ) {} + virtual KURL externalURL() const { return KURL(); } + +private: + bool m_hasFavIcon; + const KURL m_url; + QDateTime m_lastVisited; + +}; + + +#endif // HISTORY_ITEM_H diff --git a/konqueror/sidebar/trees/history_module/history_module.cpp b/konqueror/sidebar/trees/history_module/history_module.cpp new file mode 100644 index 000000000..832abd74e --- /dev/null +++ b/konqueror/sidebar/trees/history_module/history_module.cpp @@ -0,0 +1,369 @@ +/* This file is part of the KDE project + Copyright (C) 2000,2001 Carsten Pfeiffer <[email protected]> + 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qapplication.h> +#include <qpopupmenu.h> + +#include <kapplication.h> +#include <kaction.h> +#include <kcursor.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <krun.h> +#include <kstaticdeleter.h> + +#include <konq_faviconmgr.h> + +#include "history_module.h" +#include "history_settings.h" + +static KStaticDeleter<KonqSidebarHistorySettings> sd; +KonqSidebarHistorySettings * KonqSidebarHistoryModule::s_settings = 0L; + +KonqSidebarHistoryModule::KonqSidebarHistoryModule( KonqSidebarTree * parentTree, const char *name ) + : QObject( 0L, name ), KonqSidebarTreeModule( parentTree ), + m_dict( 349 ), + m_topLevelItem( 0L ), + m_dlg( 0L ), + m_initialized( false ) +{ + if ( !s_settings ) { + sd.setObject( s_settings, + new KonqSidebarHistorySettings( 0, "history settings" )); + s_settings->readSettings( true ); + } + + connect( s_settings, SIGNAL( settingsChanged() ), SLOT( slotSettingsChanged() )); + + m_dict.setAutoDelete( true ); + m_currentTime = QDateTime::currentDateTime(); + + KConfig *kc = KGlobal::config(); + KConfigGroupSaver cs( kc, "HistorySettings" ); + m_sortsByName = kc->readEntry( "SortHistory", "byDate" ) == "byName"; + + + KonqHistoryManager *manager = KonqHistoryManager::kself(); + + connect( manager, SIGNAL( loadingFinished() ), SLOT( slotCreateItems() )); + connect( manager, SIGNAL( cleared() ), SLOT( clear() )); + + connect( manager, SIGNAL( entryAdded( const KonqHistoryEntry * ) ), + SLOT( slotEntryAdded( const KonqHistoryEntry * ) )); + connect( manager, SIGNAL( entryRemoved( const KonqHistoryEntry *) ), + SLOT( slotEntryRemoved( const KonqHistoryEntry *) )); + + connect( parentTree, SIGNAL( expanded( QListViewItem * )), + SLOT( slotItemExpanded( QListViewItem * ))); + + m_collection = new KActionCollection( this, "history actions" ); + (void) new KAction( i18n("New &Window"), "window_new", 0, this, + SLOT( slotNewWindow() ), m_collection, "open_new"); + (void) new KAction( i18n("&Remove Entry"), "editdelete", 0, this, + SLOT( slotRemoveEntry() ), m_collection, "remove"); + (void) new KAction( i18n("C&lear History"), "history_clear", 0, this, + SLOT( slotClearHistory() ), m_collection, "clear"); + (void) new KAction( i18n("&Preferences..."), "configure", 0, this, + SLOT( slotPreferences()), m_collection, "preferences"); + + KRadioAction *sort; + sort = new KRadioAction( i18n("By &Name"), 0, this, + SLOT( slotSortByName() ), m_collection, "byName"); + sort->setExclusiveGroup("SortGroup"); + sort->setChecked( m_sortsByName ); + + sort = new KRadioAction( i18n("By &Date"), 0, this, + SLOT( slotSortByDate() ), m_collection, "byDate"); + sort->setExclusiveGroup("SortGroup"); + sort->setChecked( !m_sortsByName ); + + m_folderClosed = SmallIcon( "folder" ); + m_folderOpen = SmallIcon( "folder_open" ); + + slotSettingsChanged(); // read the settings +} + +KonqSidebarHistoryModule::~KonqSidebarHistoryModule() +{ + HistoryItemIterator it( m_dict ); + QStringList openGroups; + while ( it.current() ) { + if ( it.current()->isOpen() ) + openGroups.append( it.currentKey() ); + ++it; + } + + KConfig *kc = KGlobal::config(); + KConfigGroupSaver cs( kc, "HistorySettings" ); + kc->writeEntry("OpenGroups", openGroups); + kc->sync(); +} + +void KonqSidebarHistoryModule::slotSettingsChanged() +{ + KonqSidebarHistoryItem::setSettings( s_settings ); + tree()->triggerUpdate(); +} + +void KonqSidebarHistoryModule::slotCreateItems() +{ + QApplication::setOverrideCursor( KCursor::waitCursor() ); + clear(); + + KonqSidebarHistoryItem *item; + KonqHistoryEntry *entry; + KonqHistoryList entries( KonqHistoryManager::kself()->entries() ); + KonqHistoryIterator it( entries ); + m_currentTime = QDateTime::currentDateTime(); + + // the group item and the item of the serverroot '/' get a fav-icon + // if available. All others get the protocol icon. + while ( (entry = it.current()) ) { + KonqSidebarHistoryGroupItem *group = getGroupItem( entry->url ); + item = new KonqSidebarHistoryItem( entry, group, m_topLevelItem ); + + ++it; + } + + KConfig *kc = KGlobal::config(); + KConfigGroupSaver cs( kc, "HistorySettings" ); + QStringList openGroups = kc->readListEntry("OpenGroups"); + QStringList::Iterator it2 = openGroups.begin(); + KonqSidebarHistoryGroupItem *group; + while ( it2 != openGroups.end() ) { + group = m_dict.find( *it2 ); + if ( group ) + group->setOpen( true ); + + ++it2; + } + + QApplication::restoreOverrideCursor(); + m_initialized = true; +} + +// deletes the listview items but does not affect the history backend +void KonqSidebarHistoryModule::clear() +{ + m_dict.clear(); +} + +void KonqSidebarHistoryModule::slotEntryAdded( const KonqHistoryEntry *entry ) +{ + if ( !m_initialized ) + return; + + m_currentTime = QDateTime::currentDateTime(); + KonqSidebarHistoryGroupItem *group = getGroupItem( entry->url ); + KonqSidebarHistoryItem *item = group->findChild( entry ); + if ( !item ) + item = new KonqSidebarHistoryItem( entry, group, m_topLevelItem ); + else + item->update( entry ); + + // QListView scrolls when calling sort(), so we have to hack around that + // (we don't want no scrolling every time an entry is added) + KonqSidebarTree *t = tree(); + t->lockScrolling( true ); + group->sort(); + m_topLevelItem->sort(); + qApp->processOneEvent(); + t->lockScrolling( false ); +} + +void KonqSidebarHistoryModule::slotEntryRemoved( const KonqHistoryEntry *entry ) +{ + if ( !m_initialized ) + return; + + QString groupKey = groupForURL( entry->url ); + KonqSidebarHistoryGroupItem *group = m_dict.find( groupKey ); + if ( !group ) + return; + + delete group->findChild( entry ); + + if ( group->childCount() == 0 ) + m_dict.remove( groupKey ); +} + +void KonqSidebarHistoryModule::addTopLevelItem( KonqSidebarTreeTopLevelItem * item ) +{ + m_topLevelItem = item; +} + +bool KonqSidebarHistoryModule::handleTopLevelContextMenu( KonqSidebarTreeTopLevelItem *, + const QPoint& pos ) +{ + showPopupMenu( ModuleContextMenu, pos ); + return true; +} + +void KonqSidebarHistoryModule::showPopupMenu() +{ + showPopupMenu( EntryContextMenu | ModuleContextMenu, QCursor::pos() ); +} + +void KonqSidebarHistoryModule::showPopupMenu( int which, const QPoint& pos ) +{ + QPopupMenu *sortMenu = new QPopupMenu; + m_collection->action("byName")->plug( sortMenu ); + m_collection->action("byDate")->plug( sortMenu ); + + QPopupMenu *menu = new QPopupMenu; + + if ( which & EntryContextMenu ) + { + m_collection->action("open_new")->plug( menu ); + menu->insertSeparator(); + m_collection->action("remove")->plug( menu ); + } + + m_collection->action("clear")->plug( menu ); + menu->insertSeparator(); + menu->insertItem( i18n("Sort"), sortMenu ); + menu->insertSeparator(); + m_collection->action("preferences")->plug( menu ); + + menu->exec( pos ); + delete menu; + delete sortMenu; +} + +void KonqSidebarHistoryModule::slotNewWindow() +{ + kdDebug(1201)<<"void KonqSidebarHistoryModule::slotNewWindow()"<<endl; + + QListViewItem *item = tree()->selectedItem(); + KonqSidebarHistoryItem *hi = dynamic_cast<KonqSidebarHistoryItem*>( item ); + if ( hi ) + { + kdDebug(1201)<<"void KonqSidebarHistoryModule::slotNewWindow(): emitting createNewWindow"<<endl; + emit tree()->createNewWindow( hi->url() ); + } +} + +void KonqSidebarHistoryModule::slotRemoveEntry() +{ + QListViewItem *item = tree()->selectedItem(); + KonqSidebarHistoryItem *hi = dynamic_cast<KonqSidebarHistoryItem*>( item ); + if ( hi ) // remove a single entry + KonqHistoryManager::kself()->emitRemoveFromHistory( hi->externalURL()); + + else { // remove a group of entries + KonqSidebarHistoryGroupItem *gi = dynamic_cast<KonqSidebarHistoryGroupItem*>( item ); + if ( gi ) + gi->remove(); + } +} + +void KonqSidebarHistoryModule::slotPreferences() +{ + // Run the history sidebar settings. + KRun::run( "kcmshell kcmhistory", KURL::List() ); +} + +void KonqSidebarHistoryModule::slotSortByName() +{ + m_sortsByName = true; + sortingChanged(); +} + +void KonqSidebarHistoryModule::slotSortByDate() +{ + m_sortsByName = false; + sortingChanged(); +} + +void KonqSidebarHistoryModule::sortingChanged() +{ + m_topLevelItem->sort(); + + KConfig *kc = KGlobal::config(); + KConfigGroupSaver cs( kc, "HistorySettings" ); + kc->writeEntry( "SortHistory", m_sortsByName ? "byName" : "byDate" ); + kc->sync(); +} + +void KonqSidebarHistoryModule::slotItemExpanded( QListViewItem *item ) +{ + if ( item == m_topLevelItem && !m_initialized ) + slotCreateItems(); +} + +void KonqSidebarHistoryModule::groupOpened( KonqSidebarHistoryGroupItem *item, bool open ) +{ + if ( item->hasFavIcon() ) + return; + + if ( open ) + item->setPixmap( 0, m_folderOpen ); + else + item->setPixmap( 0, m_folderClosed ); +} + + +KonqSidebarHistoryGroupItem * KonqSidebarHistoryModule::getGroupItem( const KURL& url ) +{ + const QString& groupKey = groupForURL( url ); + KonqSidebarHistoryGroupItem *group = m_dict.find( groupKey ); + if ( !group ) { + group = new KonqSidebarHistoryGroupItem( url, m_topLevelItem ); + + QString icon = KonqFavIconMgr::iconForURL( url.url() ); + if ( icon.isEmpty() ) + group->setPixmap( 0, m_folderClosed ); + else + group->setFavIcon( SmallIcon( icon ) ); + + group->setText( 0, groupKey ); + + m_dict.insert( groupKey, group ); + } + + return group; +} + +void KonqSidebarHistoryModule::slotClearHistory() +{ + KGuiItem guiitem = KStdGuiItem::clear(); + guiitem.setIconSet( SmallIconSet("history_clear")); + + if ( KMessageBox::warningContinueCancel( tree(), + i18n("Do you really want to clear " + "the entire history?"), + i18n("Clear History?"), guiitem ) + == KMessageBox::Continue ) + KonqHistoryManager::kself()->emitClear(); +} + + +extern "C" +{ + KDE_EXPORT KonqSidebarTreeModule* create_konq_sidebartree_history(KonqSidebarTree* par, const bool) + { + return new KonqSidebarHistoryModule(par); + } +} + + + +#include "history_module.moc" diff --git a/konqueror/sidebar/trees/history_module/history_module.h b/konqueror/sidebar/trees/history_module/history_module.h new file mode 100644 index 000000000..30295fc3f --- /dev/null +++ b/konqueror/sidebar/trees/history_module/history_module.h @@ -0,0 +1,108 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Carsten Pfeiffer <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HISTORY_MODULE_H +#define HISTORY_MODULE_H + +#include <qdatetime.h> +#include <qobject.h> +#include <qdict.h> +#include <qpixmap.h> + +#include <kglobal.h> +#include <klocale.h> +#include <konq_sidebartreemodule.h> + +#include "history_item.h" + +class KActionCollection; +class KDialogBase; +class KonqSidebarHistorySettings; +class KonqSidebarTree; +class KonqSidebarTreeItem; + +class KonqSidebarHistoryModule : public QObject, public KonqSidebarTreeModule +{ + Q_OBJECT + +public: + enum { + ModuleContextMenu = 1, + EntryContextMenu = 2 + }; + + KonqSidebarHistoryModule( KonqSidebarTree * parentTree, const char * name = 0 ); + virtual ~KonqSidebarHistoryModule(); + + virtual void addTopLevelItem( KonqSidebarTreeTopLevelItem * item ); + virtual bool handleTopLevelContextMenu( KonqSidebarTreeTopLevelItem *item, const QPoint& pos ); + + void showPopupMenu( int which, const QPoint& pos ); + + // called by the items + void showPopupMenu(); + void groupOpened( KonqSidebarHistoryGroupItem *item, bool open ); + const QDateTime& currentTime() const { return m_currentTime; } + bool sortsByName() const { return m_sortsByName; } + + static QString groupForURL( const KURL& url ) { + static const QString& misc = KGlobal::staticQString(i18n("Miscellaneous")); + return url.host().isEmpty() ? misc : url.host(); + } + +public slots: + void clear(); + +private slots: + void slotCreateItems(); + void slotEntryAdded( const KonqHistoryEntry * ); + void slotEntryRemoved( const KonqHistoryEntry * ); + + void slotNewWindow(); + void slotRemoveEntry(); + void slotPreferences(); + void slotSettingsChanged(); + + void slotItemExpanded( QListViewItem * ); + + void slotSortByName(); + void slotSortByDate(); + + void slotClearHistory(); + +private: + KonqSidebarHistoryGroupItem *getGroupItem( const KURL& url ); + + void sortingChanged(); + typedef QDictIterator<KonqSidebarHistoryGroupItem> HistoryItemIterator; + QDict<KonqSidebarHistoryGroupItem> m_dict; + + KonqSidebarTreeTopLevelItem * m_topLevelItem; + + KActionCollection *m_collection; + + KDialogBase *m_dlg; + QPixmap m_folderClosed; + QPixmap m_folderOpen; + bool m_initialized; + bool m_sortsByName; + QDateTime m_currentTime; // used for sorting the items by date + static KonqSidebarHistorySettings *s_settings; +}; + +#endif // HISTORY_MODULE_H diff --git a/konqueror/sidebar/trees/history_module/history_settings.cpp b/konqueror/sidebar/trees/history_module/history_settings.cpp new file mode 100644 index 000000000..ed8bc7756 --- /dev/null +++ b/konqueror/sidebar/trees/history_module/history_settings.cpp @@ -0,0 +1,111 @@ + +#include <kapplication.h> +#include <kconfig.h> +#include <kglobal.h> +#include <dcopclient.h> + +#include "history_settings.h" + +KonqSidebarHistorySettings::KonqSidebarHistorySettings( QObject *parent, const char *name ) + : QObject( parent, name ), + DCOPObject( "KonqSidebarHistorySettings" ) +{ + m_fontOlderThan.setItalic( true ); // default +} + +KonqSidebarHistorySettings::KonqSidebarHistorySettings() + : QObject(), + DCOPObject( "KonqSidebarHistorySettings" ) +{ + m_fontOlderThan.setItalic( true ); // default +} + +KonqSidebarHistorySettings::KonqSidebarHistorySettings( const KonqSidebarHistorySettings& s ) + : QObject(), + DCOPObject( "KonqSidebarHistorySettings" ) +{ + m_valueYoungerThan = s.m_valueYoungerThan; + m_valueOlderThan = s.m_valueOlderThan; + + m_metricYoungerThan = s.m_metricYoungerThan; + m_metricOlderThan = s.m_metricOlderThan; + + m_detailedTips = s.m_detailedTips; + + m_fontYoungerThan = s.m_fontYoungerThan; + m_fontOlderThan = s.m_fontOlderThan; +} + +KonqSidebarHistorySettings::~KonqSidebarHistorySettings() +{ +} + +void KonqSidebarHistorySettings::readSettings(bool global) +{ + KConfig *config; + QString oldgroup; + + if (global) { + config = KGlobal::config(); + oldgroup= config->group(); + } + else + config = new KConfig("konquerorrc"); + + config->setGroup("HistorySettings"); + m_valueYoungerThan = config->readNumEntry("Value youngerThan", 1 ); + m_valueOlderThan = config->readNumEntry("Value olderThan", 2 ); + + QString minutes = QString::fromLatin1("minutes"); + QString days = QString::fromLatin1("days"); + QString metric = config->readEntry("Metric youngerThan", days ); + m_metricYoungerThan = (metric == days) ? DAYS : MINUTES; + metric = config->readEntry("Metric olderThan", days ); + m_metricOlderThan = (metric == days) ? DAYS : MINUTES; + + m_detailedTips = config->readBoolEntry("Detailed Tooltips", true); + + m_fontYoungerThan = config->readFontEntry( "Font youngerThan", + &m_fontYoungerThan ); + m_fontOlderThan = config->readFontEntry( "Font olderThan", + &m_fontOlderThan ); + if (global) + config->setGroup( oldgroup ); + else + delete config; +} + +void KonqSidebarHistorySettings::applySettings() +{ + KConfig *config = new KConfig("konquerorrc"); + config->setGroup("HistorySettings"); + + config->writeEntry("Value youngerThan", m_valueYoungerThan ); + config->writeEntry("Value olderThan", m_valueOlderThan ); + + QString minutes = QString::fromLatin1("minutes"); + QString days = QString::fromLatin1("days"); + config->writeEntry("Metric youngerThan", m_metricYoungerThan == DAYS ? + days : minutes ); + config->writeEntry("Metric olderThan", m_metricOlderThan == DAYS ? + days : minutes ); + + config->writeEntry("Detailed Tooltips", m_detailedTips); + + config->writeEntry("Font youngerThan", m_fontYoungerThan ); + config->writeEntry("Font olderThan", m_fontOlderThan ); + + delete config; + + // notify konqueror instances about the new configuration + kapp->dcopClient()->send( "konqueror*", "KonqSidebarHistorySettings", + "notifySettingsChanged()", QByteArray() ); +} + +void KonqSidebarHistorySettings::notifySettingsChanged() +{ + readSettings(false); + emit settingsChanged(); +} + +#include "history_settings.moc" diff --git a/konqueror/sidebar/trees/history_module/history_settings.h b/konqueror/sidebar/trees/history_module/history_settings.h new file mode 100644 index 000000000..21bcd01db --- /dev/null +++ b/konqueror/sidebar/trees/history_module/history_settings.h @@ -0,0 +1,66 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Carsten Pfeiffer <[email protected]> + + 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 HISTORY_SETTINGS_H +#define HISTORY_SETTINGS_H + +#include <qfont.h> +#include <qobject.h> + +#include <dcopobject.h> + +class KonqSidebarHistorySettings : public QObject, public DCOPObject +{ + K_DCOP + Q_OBJECT + +public: + enum { MINUTES, DAYS }; + + KonqSidebarHistorySettings( QObject *parent, const char *name ); + virtual ~KonqSidebarHistorySettings(); + + void readSettings(bool global); + void applySettings(); + + uint m_valueYoungerThan; + uint m_valueOlderThan; + + int m_metricYoungerThan; + int m_metricOlderThan; + + bool m_detailedTips; + + QFont m_fontYoungerThan; + QFont m_fontOlderThan; + +signals: + void settingsChanged(); + +protected: + KonqSidebarHistorySettings(); + KonqSidebarHistorySettings( const KonqSidebarHistorySettings& ); + +k_dcop: + void notifySettingsChanged(); + +private: // to make dcopidl happy :-/ +}; + +#endif // HISTORY_SETTINGS_H diff --git a/konqueror/sidebar/trees/history_module/kcmhistory.cpp b/konqueror/sidebar/trees/history_module/kcmhistory.cpp new file mode 100644 index 000000000..e4b31b232 --- /dev/null +++ b/konqueror/sidebar/trees/history_module/kcmhistory.cpp @@ -0,0 +1,272 @@ +/* + * kcmhistory.cpp + * Copyright (c) 2000,2001 Carsten Pfeiffer <[email protected]> + * Copyright (c) 2002 Stephan Binner <[email protected]> + * + * based on kcmtaskbar.cpp + * Copyright (c) 2000 Kurt Granroth <[email protected]> + * + * 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 + */ + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qradiobutton.h> + +#include <dcopclient.h> +#include <dcopref.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kdialog.h> +#include <kfontdialog.h> +#include <kgenericfactory.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <knuminput.h> +#include "history_dlg.h" + +#include "konq_historymgr.h" + +#include "kcmhistory.h" +#include "history_settings.h" + +typedef KGenericFactory<HistorySidebarConfig, QWidget > KCMHistoryFactory; +K_EXPORT_COMPONENT_FACTORY (kcm_history, KCMHistoryFactory("kcmhistory") ) + +HistorySidebarConfig::HistorySidebarConfig( QWidget *parent, const char* name, const QStringList & ) + : KCModule (KCMHistoryFactory::instance(), parent, name) +{ + KGlobal::locale()->insertCatalogue("konqueror"); + + m_settings = new KonqSidebarHistorySettings( 0, "history settings" ); + m_settings->readSettings( false ); + + QVBoxLayout *topLayout = new QVBoxLayout(this, 0, KDialog::spacingHint()); + dialog = new KonqSidebarHistoryDlg(this); + + dialog->spinEntries->setRange( 0, INT_MAX, 1, false ); + dialog->spinExpire->setRange( 0, INT_MAX, 1, false ); + + dialog->spinNewer->setRange( 0, INT_MAX, 1, false ); + dialog->spinOlder->setRange( 0, INT_MAX, 1, false ); + + dialog->comboNewer->insertItem( i18n("Minutes"), + KonqSidebarHistorySettings::MINUTES ); + dialog->comboNewer->insertItem( i18n("Days"), + KonqSidebarHistorySettings::DAYS ); + + dialog->comboOlder->insertItem( i18n("Minutes"), + KonqSidebarHistorySettings::MINUTES ); + dialog->comboOlder->insertItem( i18n("Days"), + KonqSidebarHistorySettings::DAYS ); + + connect( dialog->cbExpire, SIGNAL( toggled( bool )), + dialog->spinExpire, SLOT( setEnabled( bool ))); + connect( dialog->spinExpire, SIGNAL( valueChanged( int )), + this, SLOT( slotExpireChanged( int ))); + + connect( dialog->spinNewer, SIGNAL( valueChanged( int )), + SLOT( slotNewerChanged( int ))); + connect( dialog->spinOlder, SIGNAL( valueChanged( int )), + SLOT( slotOlderChanged( int ))); + + connect( dialog->btnFontNewer, SIGNAL( clicked() ), + SLOT( slotGetFontNewer() )); + connect( dialog->btnFontOlder, SIGNAL( clicked() ), + SLOT( slotGetFontOlder() )); + connect( dialog->btnClearHistory, SIGNAL( clicked() ), + SLOT( slotClearHistory() )); + + connect( dialog->cbDetailedTips, SIGNAL( toggled( bool )), + SLOT( configChanged() )); + connect( dialog->cbExpire, SIGNAL( toggled( bool )), + SLOT( configChanged() )); + connect( dialog->spinEntries, SIGNAL( valueChanged( int )), + SLOT( configChanged() )); + connect( dialog->comboNewer, SIGNAL( activated( int )), + SLOT( configChanged() )); + connect( dialog->comboOlder, SIGNAL( activated( int )), + SLOT( configChanged() )); + + dialog->show(); + topLayout->add(dialog); + load(); +} + +void HistorySidebarConfig::configChanged() +{ + emit changed(true); +} + +void HistorySidebarConfig::load() +{ + KConfig config("konquerorrc"); + config.setGroup("HistorySettings"); + dialog->spinExpire->setValue( config.readNumEntry( "Maximum age of History entries", 90) ); + dialog->spinEntries->setValue( config.readNumEntry( "Maximum of History entries", 500 ) ); + dialog->cbExpire->setChecked( dialog->spinExpire->value() > 0 ); + + dialog->spinNewer->setValue( m_settings->m_valueYoungerThan ); + dialog->spinOlder->setValue( m_settings->m_valueOlderThan ); + + dialog->comboNewer->setCurrentItem( m_settings->m_metricYoungerThan ); + dialog->comboOlder->setCurrentItem( m_settings->m_metricOlderThan ); + + dialog->cbDetailedTips->setChecked( m_settings->m_detailedTips ); + + m_fontNewer = m_settings->m_fontYoungerThan; + m_fontOlder = m_settings->m_fontOlderThan; + + // enable/disable widgets + dialog->spinExpire->setEnabled( dialog->cbExpire->isChecked() ); + + slotExpireChanged( dialog->spinExpire->value() ); + slotNewerChanged( dialog->spinNewer->value() ); + slotOlderChanged( dialog->spinOlder->value() ); + + emit changed(false); +} + +void HistorySidebarConfig::save() +{ + Q_UINT32 age = dialog->cbExpire->isChecked() ? dialog->spinExpire->value() : 0; + Q_UINT32 count = dialog->spinEntries->value(); + + KConfig config("konquerorrc"); + config.setGroup("HistorySettings"); + config.writeEntry( "Maximum of History entries", count ); + config.writeEntry( "Maximum age of History entries", age ); + + QByteArray dataAge; + QDataStream streamAge( dataAge, IO_WriteOnly ); + streamAge << age << "foo"; + kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", + "notifyMaxAge(Q_UINT32, QCString)", dataAge ); + + QByteArray dataCount; + QDataStream streamCount( dataCount, IO_WriteOnly ); + streamCount << count << "foo"; + kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", + "notifyMaxCount(Q_UINT32, QCString)", dataCount ); + + m_settings->m_valueYoungerThan = dialog->spinNewer->value(); + m_settings->m_valueOlderThan = dialog->spinOlder->value(); + + m_settings->m_metricYoungerThan = dialog->comboNewer->currentItem(); + m_settings->m_metricOlderThan = dialog->comboOlder->currentItem(); + + m_settings->m_detailedTips = dialog->cbDetailedTips->isChecked(); + + m_settings->m_fontYoungerThan = m_fontNewer; + m_settings->m_fontOlderThan = m_fontOlder; + + m_settings->applySettings(); + + emit changed(false); +} + +void HistorySidebarConfig::defaults() +{ + dialog->spinEntries->setValue( 500 ); + dialog->cbExpire->setChecked( true ); + dialog->spinExpire->setValue( 90 ); + + dialog->spinNewer->setValue( 1 ); + dialog->spinOlder->setValue( 2 ); + + dialog->comboNewer->setCurrentItem( KonqSidebarHistorySettings::DAYS ); + dialog->comboOlder->setCurrentItem( KonqSidebarHistorySettings::DAYS ); + + dialog->cbDetailedTips->setChecked( true ); + + m_fontNewer = QFont(); + m_fontNewer.setItalic( true ); + m_fontOlder = QFont(); + + emit changed(true); +} + +QString HistorySidebarConfig::quickHelp() const +{ + return i18n("<h1>History Sidebar</h1>" + " You can configure the history sidebar here."); +} + +void HistorySidebarConfig::slotExpireChanged( int value ) +{ + dialog->spinExpire->setSuffix( i18n(" day", " days", value) ); + configChanged(); +} + +// change hour to days, minute to minutes and the other way round, +// depending on the value of the spinbox, and synchronize the two spinBoxes +// to enfore newer <= older. +void HistorySidebarConfig::slotNewerChanged( int value ) +{ + dialog->comboNewer->changeItem( i18n ( "Day", "Days", value), + KonqSidebarHistorySettings::DAYS); + dialog->comboNewer->changeItem( i18n ( "Minute", "Minutes", value), + KonqSidebarHistorySettings::MINUTES); + + if ( dialog->spinNewer->value() > dialog->spinOlder->value() ) + dialog->spinOlder->setValue( dialog->spinNewer->value() ); + configChanged(); +} + +void HistorySidebarConfig::slotOlderChanged( int value ) +{ + dialog->comboOlder->changeItem( i18n ( "Day", "Days", value), + KonqSidebarHistorySettings::DAYS); + dialog->comboOlder->changeItem( i18n ( "Minute", "Minutes", value), + KonqSidebarHistorySettings::MINUTES); + + if ( dialog->spinNewer->value() > dialog->spinOlder->value() ) + dialog->spinNewer->setValue( dialog->spinOlder->value() ); + + configChanged(); +} + +void HistorySidebarConfig::slotGetFontNewer() +{ + int result = KFontDialog::getFont( m_fontNewer, false, this ); + if ( result == KFontDialog::Accepted ) + configChanged(); +} + +void HistorySidebarConfig::slotGetFontOlder() +{ + int result = KFontDialog::getFont( m_fontOlder, false, this ); + if ( result == KFontDialog::Accepted ) + configChanged(); +} + +void HistorySidebarConfig::slotClearHistory() +{ + KGuiItem guiitem = KStdGuiItem::clear(); + guiitem.setIconSet( SmallIconSet("history_clear")); + if ( KMessageBox::warningContinueCancel( this, + i18n("Do you really want to clear " + "the entire history?"), + i18n("Clear History?"), guiitem ) + == KMessageBox::Continue ) { + DCOPRef dcopHistManager( "konqueror*", "KonqHistoryManager" ); + dcopHistManager.send( "notifyClear", "KonqHistoryManager" ); + } +} + +#include "kcmhistory.moc" diff --git a/konqueror/sidebar/trees/history_module/kcmhistory.desktop b/konqueror/sidebar/trees/history_module/kcmhistory.desktop new file mode 100644 index 000000000..396b27b84 --- /dev/null +++ b/konqueror/sidebar/trees/history_module/kcmhistory.desktop @@ -0,0 +1,233 @@ +[Desktop Entry] +Icon=history +Type=Application +Exec=kcmshell kcmhistory + +X-KDE-ModuleType=Library +X-KDE-Library=history +X-KDE-FactoryName=history + +Name=History Sidebar +Name[af]=Geskiedenis Kantbalk +Name[ar]=الشريط الجانبي للخط الزمني +Name[az]=Keçmiş Yan Çubuğu +Name[be]=Бакавая панэль гісторыі +Name[bg]=История +Name[bn]=ইতিহাস সাইডবার +Name[bs]=Historija sidebar +Name[ca]=Barra de l'historial +Name[cs]=Panel historie +Name[csb]=Bòcznô lëstew historëji +Name[cy]=Cwpwrdd Cornel Hanes +Name[da]=Historik-sidebjælke +Name[de]=Verlaufsbereich +Name[el]=Πλευρική μπάρα ιστορικού +Name[eo]=Historia flankzono +Name[es]=Barra de historial +Name[et]=Ajaloo külgriba +Name[eu]=Historiaren alboko barra +Name[fa]=میله جانبی تاریخچه +Name[fi]=Historiasivupalkki +Name[fr]=Barre latérale d'historique +Name[fy]=Histoarje +Name[ga]=Barra Taoibh Staire +Name[gl]=Barra Lateral co Historial +Name[he]=סרגל היסטוריה +Name[hi]=इतिहास बाज़ूपट्टी +Name[hr]=Traka povijesti +Name[hu]=Napló-oldalsáv +Name[is]=Sögu hliðarslá +Name[it]=Barra laterale cronologia +Name[ja]=履歴サイドバー +Name[ka]=ისტორიის გვერდითი პანელი +Name[kk]=Бүйірдегі журнал панелі +Name[km]=របារប្រវត្តិ +Name[ko]=과거 기록 사이드바 +Name[lo]=ປະວັດການໃໍຊ້ງານ +Name[lt]=Istorijos šoninė juosta +Name[lv]=Vēstures sānjosla +Name[mk]=Лента за историја +Name[mn]=Түүхийн хуудас +Name[ms]=Bar Sisi Sejarah +Name[mt]=Kronoloġija +Name[nb]=Historie-sidestolpe +Name[nds]=Vörgeschicht-Sietpaneel +Name[ne]=इतिहास छेउपट्टी +Name[nl]=Geschiedenis +Name[nn]=Historie-sidestolpe +Name[nso]=Bar ya lehlakori ya Histori +Name[pa]=ਅਤੀਤ ਪਾਸੇ ਪੱਟੀ +Name[pl]=Pasek boczny z historią +Name[pt]=Barra Lateral do Histórico +Name[pt_BR]=Barra Lateral de Histórico +Name[ro]=Bară laterală de istoric +Name[ru]=Журнал +Name[rw]=Umurongokuruhande w'Amateka +Name[se]=Historihkkaholga +Name[sk]=Bočný panel histórie +Name[sl]=Stranska vrstica zgodovine +Name[sr]=Бочни панел историјата +Name[sr@Latn]=Bočni panel istorijata +Name[sv]=Historiksidopanel +Name[ta]=வரலாற்றுப் பக்கப்பட்டி +Name[tg]=Паҳлӯи сафҳаи торихча +Name[th]=แถบประวัติการใช้ด้านข้าง +Name[tr]=Geçmiş Yan Çubuğu +Name[tt]=Taríx Yantiräse +Name[uk]=Бічна панель історії +Name[uz]=Tarix paneli +Name[uz@cyrillic]=Тарих панели +Name[ven]=Bara ya lurumbu ya Divhazwakale +Name[vi]=Bảng Lịch sử +Name[wa]=Bår di costé di l' istwere +Name[xh]=Ibar esecaleni Yembali +Name[zh_CN]=历史侧边栏 +Name[zh_TW]=歷史紀錄邊列 +Name[zu]=Umlando webha yaseceleni +Comment=Configure the history sidebar +Comment[af]=Stel die geskiedenis kantbalk op +Comment[ar]=إعداد الشريط الجانبي للخط الزمني +Comment[az]=Keçmiş yan çubuğunu quraşdır +Comment[be]=Настаўленне бакавой панэлі гісторыі +Comment[bg]=Настройване на историята +Comment[bn]=ইতিহাস সাইডবার কনফিগার করুন +Comment[bs]=Ovdje možete podesiti history sidebar +Comment[ca]=Configura la barra de l'historial +Comment[cs]=Nastavení panelu historie +Comment[csb]=Kònfigùracëjô bòczny lëstwë historëji +Comment[cy]=Ffurfweddu'r cwpwrdd cornel hanes +Comment[da]=Indstil historik-sidebjælken +Comment[de]=Verlaufsanzeige im Navigationsbereich einrichten +Comment[el]=Ρυθμίστε την πλευρική μπάρα ιστορικού +Comment[eo]=Agordo de la historia flankzono +Comment[es]=Configuración de la barra del historial +Comment[et]=Ajaloo külgriba seadistamine +Comment[eu]=Konfiguratu historiaren alboko barra +Comment[fa]=پیکربندی میله جانبی تاریخچه +Comment[fi]=Historiasivupalkin asetukset +Comment[fr]=Configuration de l'historique de la barre latérale +Comment[fy]=Hjir kinne jo de histoarje ynstelle +Comment[ga]=Cumraigh an barra taoibh staire +Comment[gl]=Configurar o historial da barra lateral +Comment[he]=שינוי הגדרות הסרגל הצדדי של ההיסטוריה +Comment[hi]=इतिहास बाज़ूपट्टी कॉन्फ़िगर करें +Comment[hr]=Konfiguriranje trake povijesti +Comment[hu]=A napló-oldalsáv beállításai +Comment[is]=Stilla hliðardálk með flakksögu +Comment[it]=Configura la barra laterale della cronologia +Comment[ja]=履歴サイドバーの設定 +Comment[ka]=ისტორიის გვერდითი პანელის კონფიგურირება +Comment[kk]=Бүйірдегі журнал панелін баптау +Comment[km]=កំណត់រចនាសម្ព័ន្ធរបារប្រវត្តិ +Comment[ko]=과거 기록 사이드바를 설정합니다 +Comment[lo]=ທ່ານສາມາດປັບແຕ່ງຖາດພາເນລແຖບຫນ້າຕ່າງງານ ໄດ້ທີ່ນີ້ +Comment[lt]=Konfigūruoti istorijos šoninę juostą +Comment[lv]=Šeit jūs varat konfigurēt vēstures sānjoslu +Comment[mk]=Конфигурација на лентата за историја +Comment[mn]=Түүхийн хуудас тохируулах +Comment[ms]=Konfigur bar sisi sejarah +Comment[mt]=Ikkonfigura l-wirja tal-kronoloġija +Comment[nb]=Tilpass historiesidestolpen +Comment[nds]=Dat Vörgeschicht-Sietpaneel instellen +Comment[ne]=इतिहास छेउपट्टी कन्फिगर गर्नुहोस् +Comment[nl]=Hier kunt u de geschiedenis instellen +Comment[nn]=Set opp historie-sidestolpen +Comment[nso]=Beakanya bar ya lehlakori ya histori +Comment[pa]=ਅਤੀਤ ਬਾਹੀ ਸੰਰਚਨਾ +Comment[pl]=Konfiguracja paska bocznego z historią +Comment[pt]=Configuração da barra lateral do histórico +Comment[pt_BR]=Configura a barra lateral de Histórico +Comment[ro]=Configurează bara laterală de URL-uri vizitate +Comment[ru]=Настройка боковой панели журнала +Comment[rw]=Kuboneza umurongokuruhande w'amateka +Comment[se]=Heivet historihkkaholgga +Comment[sk]=Nastavenie bočného panelu histórie +Comment[sl]=Nastavitve stranske vrstice zgodovine +Comment[sr]=Подешавање бочног панела историјата +Comment[sr@Latn]=Podešavanje bočnog panela istorijata +Comment[sv]=Anpassa historiksidopanelen +Comment[ta]=வரலாறு பக்கப்பட்டியலை வடிவமை +Comment[tg]=Танзимоти паҳлӯи сафҳаи торихча +Comment[th]=ปรับแต่งแถบประวัติการใช้ด้านข้าง +Comment[tr]=Geçmiş yan çubuğunu yapılandır +Comment[tt]="Uzğanı" yantiräseneñ caylawı +Comment[uk]=Налаштування бічної панелі історії +Comment[uz]=Tarix panelini moslash +Comment[uz@cyrillic]=Тарих панелини мослаш +Comment[ven]=Dzudzanyani bara ya lurumbu lwa divhazwakale +Comment[vi]=Cấu hình bảng nằm bên cạnh chứa lịch sử duyệt mạng +Comment[wa]=Apontyî l' dujhance del bår di costé d' istwere +Comment[xh]=Qwalasela imbali ye bar yasecaleni +Comment[zh_CN]=配置任务侧边栏 +Comment[zh_TW]=設定歷史紀錄邊列 +Comment[zu]=Hlanganisela ibha yaseceleni yomlando +Keywords=history,expire +Keywords[ar]=الخط الزمني, إنتهاء الأجل +Keywords[az]=history,expire,keçmiş +Keywords[be]=Гісторыя,Састарэлая,history,expire +Keywords[bg]=история, сърфиране, срок, изтичане, history, expire +Keywords[ca]=historial,expira +Keywords[cs]=historie,vypršení +Keywords[csb]=historëjô,wëgasëwanié +Keywords[cy]=hanes,daw i ben +Keywords[da]=historik,udløbe +Keywords[de]=History,Verlauf +Keywords[el]=ιστορικό,λήξη +Keywords[eo]=historio,malvalidiĝi +Keywords[es]=historial,expirar +Keywords[et]=ajalugu,aegumine +Keywords[eu]=historia,iraungi +Keywords[fa]=تاریخچه، انقضا +Keywords[fi]=historia,umpeenmeno +Keywords[fr]=historique,expiration +Keywords[fy]=histoarje,ferrinne +Keywords[ga]=stair,caite,as feidhm +Keywords[gl]=historial,caducar +Keywords[he]=היסטוריה,תפוגה,history,expire +Keywords[hi]=इतिहास,बीत गया +Keywords[hr]=history,expire,povijest,istek +Keywords[hu]=napló,lejárás +Keywords[is]=Saga,útrunnið,history +Keywords[it]=cronologia,scadenza +Keywords[ja]=履歴,失効 +Keywords[km]=ប្រវត្តិ ផុតកំណត់ +Keywords[lo]=ໃຊ້ຮ່ວມກັນ +Keywords[lt]=history,expire, istorija,pasibaigti +Keywords[lv]=vēsture,beigties +Keywords[mk]=history,expire,историја,истекува +Keywords[mn]=Түүх,Дуусах +Keywords[ms]=sejarah, luput +Keywords[mt]=history,expire,kronoloġija,skadi +Keywords[nb]=historie,utløper +Keywords[nds]=Vörgeschicht,aflopen +Keywords[ne]=इतिहास, म्याद समाप्त +Keywords[nl]=geschiedenis,verloop +Keywords[nn]=historie,utgår +Keywords[nso]=histori,felelwa ke nako +Keywords[pa]=expire,ਅਤੀਤ +Keywords[pl]=historia,wygasanie +Keywords[pt]=histórico,expirar +Keywords[pt_BR]=histórico,expirar +Keywords[ro]=istoric,expirare +Keywords[ru]=history,expire,журнал +Keywords[rw]=amateka,kurangiza igihe +Keywords[se]=historihkka,boarásnuvvat +Keywords[sk]=história,vypršanie +Keywords[sl]=zgodovina,potek,poteče +Keywords[sr]=history,expire,историјат,истицање +Keywords[sr@Latn]=history,expire,istorijat,isticanje +Keywords[sv]=historik,utgå +Keywords[ta]=வரலாறு,முடிந்தது +Keywords[th]=ประวัติการใช้,หมดอายุ +Keywords[tr]=geçmiş +Keywords[uk]=історія,закінчення терміну,втрата чинності +Keywords[uz]=tarix,muddati oʻtish +Keywords[uz@cyrillic]=тарих,муддати ўтиш +Keywords[ven]=divhazwakale,fhelelwa nga tshifhinga +Keywords[vi]=lịch sử,hết hạn +Keywords[wa]=istwere,espirer,espiraedje +Keywords[xh]=imbali,ephelelwa lixesha +Keywords[zh_CN]=history,expire,历史,过期 +Keywords[zh_TW]=history,expire,歷史紀錄,過期 +Keywords[zu]=umlando,ukuphelelwa isikhathi +Categories=Qt;KDE;X-KDE-settings-webbrowsing; diff --git a/konqueror/sidebar/trees/history_module/kcmhistory.h b/konqueror/sidebar/trees/history_module/kcmhistory.h new file mode 100644 index 000000000..5eaaf3a64 --- /dev/null +++ b/konqueror/sidebar/trees/history_module/kcmhistory.h @@ -0,0 +1,64 @@ +/* + * kcmhistory.h + * Copyright (c) 2002 Stephan Binner <[email protected]> + * + * based on kcmtaskbar.h + * Copyright (c) 2000 Kurt Granroth <[email protected]> + * + * 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 + */ +#ifndef __kcmhistory_h__ +#define __kcmhistory_h__ + +#include <kcmodule.h> + +class KonqHistoryManager; +class KonqSidebarHistorySettings; +class KonqSidebarHistoryDlg; + +class HistorySidebarConfig : public KCModule +{ + Q_OBJECT + +public: + HistorySidebarConfig( QWidget *parent=0, const char* name=0, const QStringList &list=QStringList() ); + + void load(); + void save(); + void defaults(); + + QString quickHelp() const; + +private slots: + void configChanged(); + + void slotGetFontNewer(); + void slotGetFontOlder(); + + void slotExpireChanged( int ); + void slotNewerChanged( int ); + void slotOlderChanged( int ); + + void slotClearHistory(); + +private: + QFont m_fontNewer; + QFont m_fontOlder; + + KonqSidebarHistoryDlg* dialog; + KonqSidebarHistorySettings *m_settings; + KonqHistoryManager *mgr; +}; + +#endif diff --git a/konqueror/sidebar/trees/init/Makefile.am b/konqueror/sidebar/trees/init/Makefile.am new file mode 100644 index 000000000..58c6186b0 --- /dev/null +++ b/konqueror/sidebar/trees/init/Makefile.am @@ -0,0 +1,16 @@ +SUBDIRS = remote services + +dataEntry_DATA = home.desktop root.desktop history.desktop bookmarks.desktop \ + services.desktop remote.desktop system.desktop +dataEntrydir = $(kde_datadir)/konqsidebartng/entries + +dataKickerEntries_DATA = home.desktop root.desktop history.desktop bookmarks.desktop \ + services.desktop remote.desktop +dataKickerEntriesdir = $(kde_datadir)/konqsidebartng/kicker_entries + + +dataAdd_DATA = virtualfolderadd.desktop +dataAdddir = $(kde_datadir)/konqsidebartng/add + +dataPlugins_DATA = history_module.desktop dirtree_module.desktop bookmarks_module.desktop +dataPluginsdir = $(kde_datadir)/konqsidebartng/dirtree diff --git a/konqueror/sidebar/trees/init/README b/konqueror/sidebar/trees/init/README new file mode 100644 index 000000000..c0907a3ae --- /dev/null +++ b/konqueror/sidebar/trees/init/README @@ -0,0 +1,6 @@ +Note: increase the version in konq_tree.cpp when you add + new .desktop files, otherwise they won't get used + when the user already has old versions. + +i.e. +const int currentVersion = 5; <-- change this in konq_tree.cpp diff --git a/konqueror/sidebar/trees/init/bookmarks.desktop b/konqueror/sidebar/trees/init/bookmarks.desktop new file mode 100644 index 000000000..1707aba6b --- /dev/null +++ b/konqueror/sidebar/trees/init/bookmarks.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Type=Link +URL= +Icon=bookmark +Name=Bookmarks +Name[af]=Boekmerke +Name[ar]=علامات المواقع +Name[az]=Nişanlar +Name[be]=Закладкі +Name[bg]=Отметки +Name[bn]=বুকমার্ক +Name[br]=Sinedoù +Name[bs]=Zabilješke +Name[ca]=Punts +Name[cs]=Záložky +Name[csb]=Załóżczi +Name[cy]=Nodau Tudalen +Name[da]=Bogmærker +Name[de]=Lesezeichen +Name[el]=Σελιδοδείκτες +Name[eo]=Legosignoj +Name[es]=Marcadores +Name[et]=Järjehoidjad +Name[eu]=Laster-markak +Name[fa]=چوب الفها +Name[fi]=Kirjanmerkit +Name[fr]=Signets +Name[fy]=Blêdwizers +Name[ga]=Leabharmharcanna +Name[gl]=Marcadores +Name[he]=סימניות +Name[hi]= पसंदीदा +Name[hr]=Oznake +Name[hu]=Könyvjelzők +Name[id]=Bookmark +Name[is]=Bókamerki +Name[it]=Segnalibri +Name[ja]=ブックマーク +Name[ka]=სანიშნეები +Name[kk]=Бетбелгі +Name[km]=ចំណាំ +Name[ko]=책갈피 +Name[lo]=ທີ່ຄັ້ນປື້ມ +Name[lt]=Žymelės +Name[lv]=Grāmatzīmes +Name[mk]=Обележувачи +Name[mn]=Хавчуурга +Name[ms]=Tanda Buku +Name[mt]=Favoriti +Name[nb]=Bokmerker +Name[nds]=Leesteken +Name[ne]=पुस्तकचिनो +Name[nl]=Bladwijzers +Name[nn]=Bokmerke +Name[nso]=Ditshwao tsa Buka +Name[pa]=ਬੁੱਕਮਾਰਕ +Name[pl]=Zakładki +Name[pt]=Favoritos +Name[pt_BR]=Favoritos +Name[ro]=Semne de carte +Name[ru]=Закладки +Name[rw]=Utumenyetso +Name[se]=Girjemearkkat +Name[sk]=Záložky +Name[sl]=Zaznamki +Name[sr]=Маркери +Name[sr@Latn]=Markeri +Name[sv]=Bokmärken +Name[ta]=புத்தகக்குறிகள் +Name[te]=పేజి గుర్తులు +Name[tg]=Гузориш +Name[th]=ที่คั่นหน้า +Name[tr]=Yer imleri +Name[tt]=Bitbilge +Name[uk]=Закладки +Name[uz]=Xatchoʻplar +Name[uz@cyrillic]=Хатчўплар +Name[ven]=Dzitswayo dza bugu +Name[vi]=Sổ lưu địa chỉ +Name[wa]=Rimåkes +Name[xh]=Amanqaku eencwadi +Name[zh_CN]=书签 +Name[zh_TW]=書籤 +Name[zu]=Omaka bencwadi +Comment=This is the list of your bookmarks, for a faster access +Comment[af]=Hierdie is die lys van jou boekmerke, vir 'n vinniger toegang verkry +Comment[ar]=هذه قائمة بمواقعك المفضلة من أجل وصول أسرع +Comment[az]=Bunlar daha asan yetişmək üçün toplanan nişanlarınızdır +Comment[be]=Гэта спіс вашых закладак для хуткага доступу +Comment[bg]=Списък на отметки за бърз достъп +Comment[bn]=আপনার বুকমার্কের তালিকা, পছন্দের গন্তব্যে চটপট পৌঁছে যাবার জন্য +Comment[bs]=Ovo je lista vaših zabiljeških, za brži pristup +Comment[ca]=Aquesta és la llista dels vostres punts, per un accés més ràpid +Comment[cs]=Toto je seznam vašich záložek k jejich rychlejšímu nalezení +Comment[csb]=To je lësta załóżków, dlô chùtczégò przistãpù +Comment[cy]=Dyma restr eich nodau tudalen, am gyrchiad cyflymach +Comment[da]=Dette er en liste af dine bogmærker for hurtigere adgang +Comment[de]=Dies ist eine Liste Ihrer Lesezeichen, sie dient dem schnelleren Zugriff +Comment[el]=Αυτή είναι η λίστα των σελιδοδεικτών σας, για γρηγορότερη πρόσβαση +Comment[eo]=Jen la listo de viaj legosignoj por pli rapida aliro +Comment[es]=Esta es la lista de sus marcadores, para un acceso más rápido. +Comment[et]=Sinu järjehoidjate nimekiri +Comment[eu]=Hemen duzu zure laster-marken zerrenda, atzitze bizkorragorako +Comment[fa]=این فهرست چوب الفهای شما، برای دستیابی سریعتر است +Comment[fi]=Tämä on lista kirjanmerkeistäsi +Comment[fr]=Voici la liste de vos signets, afin que vous y accédiez plus rapidement +Comment[fy]=Dit is de list mei jo blêdwizers, foar fluggere tagong +Comment[ga]=Seo liosta do chuid leabharmharcanna, le haghaidh rochtain níos tapúla +Comment[gl]=Ésta é a lista dos seus marcadores, para un aceso máis rápido +Comment[he]=זוהי רשימת הסימניות שלך, לגישה מהירה +Comment[hi]=यह आपकी पसंद की सूची है, तेजी से पहुँच के लिए +Comment[hr]=Popis oznaka koje ubrzavaju pristup +Comment[hu]=A könyvjelzők listája (gyors elérhetőség) +Comment[is]=Hér eru bókamerkin þín +Comment[it]=Questa è la lista dei tuoi segnalibri, per un accesso più rapido +Comment[ja]=高速アクセスのためのブックマークのリストです +Comment[ka]=ეს არის თვენი სანიშნეების სია, რომელიც გჭირდებათ სწრაფად წვდომისთვის +Comment[kk]=Тез ақтару үшін бетбелгі тізіміңіз +Comment[km]=នេះជាបញ្ជីចំណាំរបស់អ្នក ដែលអាចចូលដំណើរការបានលឿន +Comment[ko]=빠른 접근을 위한 책갈피 목록입니다 +Comment[lo]=ນີ້ເປັນລາຍການທີ່ຄັ້ນປື້ມຂອງທ່ານ ເພື່ການຮງກໃຊ້ຢ່າງໄວร็ว +Comment[lt]=Šiame aplanke yra visos Jūsų žymelės, skirtos greitesniam priėjimui +Comment[lv]=Šis ir jūsu grāmatzīmju saraksts ātrākai pieejai +Comment[mk]=Ова е листа на вашите обележувачи што служат за побрз пристап +Comment[mn]=Энэ бол таны хавчуургын жагсаалт ба таньд хурдан хандах боломж олгоно. +Comment[ms]=Ini ialah senarai tanda buku anda, untuk akses terpantas +Comment[mt]=Din hija lista tal-favoriti tiegħek, għal aċċess ta' malajr +Comment[nb]=Dette er en liste over bokmerkene dine, for raskere tilgang +Comment[nds]=Dat is de List vun Dien Leesteken för gauen Togriep +Comment[ne]=छिटो पहुँचका लागि यो तपाईँको पुस्तकचिनो सूची हो +Comment[nl]=Dit is de lijst met uw bladwijzers, voor snellere toegang +Comment[nn]=Dette er ei liste over bokmerka dine, for snøggare tilgang +Comment[nso]=Ye ke palo ya ditshwao tsa gago tsa buka,go tsenelo ya kapela +Comment[pa]=ਤੇਜ਼ ਖੋਲਣ ਲਈ ਇਹ ਤੁਹਾਡੇ ਬੁੱਕਮਾਰਕ ਦੀ ਸੂਚੀ ਹੈ +Comment[pl]=To jest lista zakładek, dla szybszego dostępu +Comment[pt]=Os seus favoritos, para um acesso mais rápido +Comment[pt_BR]=Esta pasta contém a sua lista dos favoritos, para o acesso mais rápido +Comment[ro]=Aceasta este lista semnelor dumneavoastră de carte +Comment[ru]=Список закладок для быстрого доступа +Comment[rw]=Uru ni urutonde rw'utumenyetso twawe, k'ukugera kwihuse +Comment[se]=Dát leat du girjemearkkat, álkibut gávdnat +Comment[sk]=Toto je zoznam vašich záložiek, pre rýchlejší prístup k nim +Comment[sl]=To je seznam vaših zaznamkov, za hitrejši dostop. +Comment[sr]=Ово је листа ваших маркера, ради лакшег приступа +Comment[sr@Latn]=Ovo je lista vaših markera, radi lakšeg pristupa +Comment[sv]=Det här är listan på dina bokmärken, för snabbare åtkomst +Comment[ta]=இந்த பட்டியல் உங்கள் புத்தக குறியீடுகளை விரைவாற் அணுகுவதற்கு. +Comment[tg]=Рӯйхати гузориш барои дастраси тез +Comment[th]=นี่เป็นรายการที่คั่นหน้าของคุณ เพื่อการเรียกใช้อย่างรวดเร็ว +Comment[tr]=Bu sizin daha hızlı erişiminiz için kısa yollarınızın bir listesidir +Comment[tt]=Tiz ireşü öçen bitbilgelär tezmäse +Comment[uk]=Це - список ваших закладок для швидкого доступу +Comment[uz]=Xatchoʻplar roʻyxati +Comment[uz@cyrillic]=Хатчўплар рўйхати +Comment[ven]=Hoyu ndi mutevhe wa tswayo dza bugu, uitele u dzhene ngau tavhanya +Comment[vi]=Đây là danh sách tất cả các địa chỉ đã lưu của bạn, giúp cho truy cập nhanh hơn +Comment[wa]=Cichal est l' djivêye di vos rmåkes, po les trover pus rade +Comment[xh]=Olu luluhlu lwamanqaku encwadi yakho, yonikezelo olukhawulezayo +Comment[zh_CN]=这是您的书签列表,以便使得访问更加方便 +Comment[zh_TW]=快速存取網站的書籤列表 +Comment[zu]=Lolu uhlu lomaka bakho bencwadi,ukuze ungene ngokushesha +Open=false +X-KDE-TreeModule=Bookmarks +X-KDE-SearchableTreeModule=true +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/bookmarks_module.desktop b/konqueror/sidebar/trees/init/bookmarks_module.desktop new file mode 100644 index 000000000..4f6c96324 --- /dev/null +++ b/konqueror/sidebar/trees/init/bookmarks_module.desktop @@ -0,0 +1,166 @@ +[Desktop Entry] +Type=Link +URL= +Icon=bookmark +Name=Bookmarks +Name[af]=Boekmerke +Name[ar]=علامات المواقع +Name[az]=Nişanlar +Name[be]=Закладкі +Name[bg]=Отметки +Name[bn]=বুকমার্ক +Name[br]=Sinedoù +Name[bs]=Zabilješke +Name[ca]=Punts +Name[cs]=Záložky +Name[csb]=Załóżczi +Name[cy]=Nodau Tudalen +Name[da]=Bogmærker +Name[de]=Lesezeichen +Name[el]=Σελιδοδείκτες +Name[eo]=Legosignoj +Name[es]=Marcadores +Name[et]=Järjehoidjad +Name[eu]=Laster-markak +Name[fa]=چوب الفها +Name[fi]=Kirjanmerkit +Name[fr]=Signets +Name[fy]=Blêdwizers +Name[ga]=Leabharmharcanna +Name[gl]=Marcadores +Name[he]=סימניות +Name[hi]= पसंदीदा +Name[hr]=Oznake +Name[hu]=Könyvjelzők +Name[id]=Bookmark +Name[is]=Bókamerki +Name[it]=Segnalibri +Name[ja]=ブックマーク +Name[ka]=სანიშნეები +Name[kk]=Бетбелгі +Name[km]=ចំណាំ +Name[ko]=책갈피 +Name[lo]=ທີ່ຄັ້ນປື້ມ +Name[lt]=Žymelės +Name[lv]=Grāmatzīmes +Name[mk]=Обележувачи +Name[mn]=Хавчуурга +Name[ms]=Tanda Buku +Name[mt]=Favoriti +Name[nb]=Bokmerker +Name[nds]=Leesteken +Name[ne]=पुस्तकचिनो +Name[nl]=Bladwijzers +Name[nn]=Bokmerke +Name[nso]=Ditshwao tsa Buka +Name[pa]=ਬੁੱਕਮਾਰਕ +Name[pl]=Zakładki +Name[pt]=Favoritos +Name[pt_BR]=Favoritos +Name[ro]=Semne de carte +Name[ru]=Закладки +Name[rw]=Utumenyetso +Name[se]=Girjemearkkat +Name[sk]=Záložky +Name[sl]=Zaznamki +Name[sr]=Маркери +Name[sr@Latn]=Markeri +Name[sv]=Bokmärken +Name[ta]=புத்தகக்குறிகள் +Name[te]=పేజి గుర్తులు +Name[tg]=Гузориш +Name[th]=ที่คั่นหน้า +Name[tr]=Yer imleri +Name[tt]=Bitbilge +Name[uk]=Закладки +Name[uz]=Xatchoʻplar +Name[uz@cyrillic]=Хатчўплар +Name[ven]=Dzitswayo dza bugu +Name[vi]=Sổ lưu địa chỉ +Name[wa]=Rimåkes +Name[xh]=Amanqaku eencwadi +Name[zh_CN]=书签 +Name[zh_TW]=書籤 +Name[zu]=Omaka bencwadi +Comment=This is the list of your bookmarks, for a faster access +Comment[af]=Hierdie is die lys van jou boekmerke, vir 'n vinniger toegang verkry +Comment[ar]=هذه قائمة بمواقعك المفضلة من أجل وصول أسرع +Comment[az]=Bunlar daha asan yetişmək üçün toplanan nişanlarınızdır +Comment[be]=Гэта спіс вашых закладак для хуткага доступу +Comment[bg]=Списък на отметки за бърз достъп +Comment[bn]=আপনার বুকমার্কের তালিকা, পছন্দের গন্তব্যে চটপট পৌঁছে যাবার জন্য +Comment[bs]=Ovo je lista vaših zabiljeških, za brži pristup +Comment[ca]=Aquesta és la llista dels vostres punts, per un accés més ràpid +Comment[cs]=Toto je seznam vašich záložek k jejich rychlejšímu nalezení +Comment[csb]=To je lësta załóżków, dlô chùtczégò przistãpù +Comment[cy]=Dyma restr eich nodau tudalen, am gyrchiad cyflymach +Comment[da]=Dette er en liste af dine bogmærker for hurtigere adgang +Comment[de]=Dies ist eine Liste Ihrer Lesezeichen, sie dient dem schnelleren Zugriff +Comment[el]=Αυτή είναι η λίστα των σελιδοδεικτών σας, για γρηγορότερη πρόσβαση +Comment[eo]=Jen la listo de viaj legosignoj por pli rapida aliro +Comment[es]=Esta es la lista de sus marcadores, para un acceso más rápido. +Comment[et]=Sinu järjehoidjate nimekiri +Comment[eu]=Hemen duzu zure laster-marken zerrenda, atzitze bizkorragorako +Comment[fa]=این فهرست چوب الفهای شما، برای دستیابی سریعتر است +Comment[fi]=Tämä on lista kirjanmerkeistäsi +Comment[fr]=Voici la liste de vos signets, afin que vous y accédiez plus rapidement +Comment[fy]=Dit is de list mei jo blêdwizers, foar fluggere tagong +Comment[ga]=Seo liosta do chuid leabharmharcanna, le haghaidh rochtain níos tapúla +Comment[gl]=Ésta é a lista dos seus marcadores, para un aceso máis rápido +Comment[he]=זוהי רשימת הסימניות שלך, לגישה מהירה +Comment[hi]=यह आपकी पसंद की सूची है, तेजी से पहुँच के लिए +Comment[hr]=Popis oznaka koje ubrzavaju pristup +Comment[hu]=A könyvjelzők listája (gyors elérhetőség) +Comment[is]=Hér eru bókamerkin þín +Comment[it]=Questa è la lista dei tuoi segnalibri, per un accesso più rapido +Comment[ja]=高速アクセスのためのブックマークのリストです +Comment[ka]=ეს არის თვენი სანიშნეების სია, რომელიც გჭირდებათ სწრაფად წვდომისთვის +Comment[kk]=Тез ақтару үшін бетбелгі тізіміңіз +Comment[km]=នេះជាបញ្ជីចំណាំរបស់អ្នក ដែលអាចចូលដំណើរការបានលឿន +Comment[ko]=빠른 접근을 위한 책갈피 목록입니다 +Comment[lo]=ນີ້ເປັນລາຍການທີ່ຄັ້ນປື້ມຂອງທ່ານ ເພື່ການຮງກໃຊ້ຢ່າງໄວร็ว +Comment[lt]=Šiame aplanke yra visos Jūsų žymelės, skirtos greitesniam priėjimui +Comment[lv]=Šis ir jūsu grāmatzīmju saraksts ātrākai pieejai +Comment[mk]=Ова е листа на вашите обележувачи што служат за побрз пристап +Comment[mn]=Энэ бол таны хавчуургын жагсаалт ба таньд хурдан хандах боломж олгоно. +Comment[ms]=Ini ialah senarai tanda buku anda, untuk akses terpantas +Comment[mt]=Din hija lista tal-favoriti tiegħek, għal aċċess ta' malajr +Comment[nb]=Dette er en liste over bokmerkene dine, for raskere tilgang +Comment[nds]=Dat is de List vun Dien Leesteken för gauen Togriep +Comment[ne]=छिटो पहुँचका लागि यो तपाईँको पुस्तकचिनो सूची हो +Comment[nl]=Dit is de lijst met uw bladwijzers, voor snellere toegang +Comment[nn]=Dette er ei liste over bokmerka dine, for snøggare tilgang +Comment[nso]=Ye ke palo ya ditshwao tsa gago tsa buka,go tsenelo ya kapela +Comment[pa]=ਤੇਜ਼ ਖੋਲਣ ਲਈ ਇਹ ਤੁਹਾਡੇ ਬੁੱਕਮਾਰਕ ਦੀ ਸੂਚੀ ਹੈ +Comment[pl]=To jest lista zakładek, dla szybszego dostępu +Comment[pt]=Os seus favoritos, para um acesso mais rápido +Comment[pt_BR]=Esta pasta contém a sua lista dos favoritos, para o acesso mais rápido +Comment[ro]=Aceasta este lista semnelor dumneavoastră de carte +Comment[ru]=Список закладок для быстрого доступа +Comment[rw]=Uru ni urutonde rw'utumenyetso twawe, k'ukugera kwihuse +Comment[se]=Dát leat du girjemearkkat, álkibut gávdnat +Comment[sk]=Toto je zoznam vašich záložiek, pre rýchlejší prístup k nim +Comment[sl]=To je seznam vaših zaznamkov, za hitrejši dostop. +Comment[sr]=Ово је листа ваших маркера, ради лакшег приступа +Comment[sr@Latn]=Ovo je lista vaših markera, radi lakšeg pristupa +Comment[sv]=Det här är listan på dina bokmärken, för snabbare åtkomst +Comment[ta]=இந்த பட்டியல் உங்கள் புத்தக குறியீடுகளை விரைவாற் அணுகுவதற்கு. +Comment[tg]=Рӯйхати гузориш барои дастраси тез +Comment[th]=นี่เป็นรายการที่คั่นหน้าของคุณ เพื่อการเรียกใช้อย่างรวดเร็ว +Comment[tr]=Bu sizin daha hızlı erişiminiz için kısa yollarınızın bir listesidir +Comment[tt]=Tiz ireşü öçen bitbilgelär tezmäse +Comment[uk]=Це - список ваших закладок для швидкого доступу +Comment[uz]=Xatchoʻplar roʻyxati +Comment[uz@cyrillic]=Хатчўплар рўйхати +Comment[ven]=Hoyu ndi mutevhe wa tswayo dza bugu, uitele u dzhene ngau tavhanya +Comment[vi]=Đây là danh sách tất cả các địa chỉ đã lưu của bạn, giúp cho truy cập nhanh hơn +Comment[wa]=Cichal est l' djivêye di vos rmåkes, po les trover pus rade +Comment[xh]=Olu luluhlu lwamanqaku encwadi yakho, yonikezelo olukhawulezayo +Comment[zh_CN]=这是您的书签列表,以便使得访问更加方便 +Comment[zh_TW]=快速存取網站的書籤列表 +Comment[zu]=Lolu uhlu lomaka bakho bencwadi,ukuze ungene ngokushesha +Open=false +X-KDE-TreeModule=Bookmarks +X-KDE-SearchableTreeModule=true +X-KDE-TreeModule-Lib=konq_sidebartree_bookmarks +X-KDE-Default-URL= diff --git a/konqueror/sidebar/trees/init/dirtree_module.desktop b/konqueror/sidebar/trees/init/dirtree_module.desktop new file mode 100644 index 000000000..7db283eb2 --- /dev/null +++ b/konqueror/sidebar/trees/init/dirtree_module.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=Link +URL= +Icon=folder +Name=Folder +Name[af]=Gids +Name[ar]=المجلد +Name[az]=Qovluq +Name[be]=Тэчка +Name[bg]=Директория +Name[bn]=ফোল্ডার +Name[br]=Renkell +Name[bs]=Direktorij +Name[ca]=Carpeta +Name[cs]=Složka +Name[csb]=Katalog +Name[cy]=Plygell +Name[da]=Mappe +Name[de]=Ordner +Name[el]=Φάκελος +Name[eo]=Dosierujo +Name[es]=Carpeta +Name[et]=Kataloog +Name[eu]=Karpeta +Name[fa]=پوشه +Name[fi]=Kansio +Name[fr]=Dossier +Name[fy]=Map +Name[ga]=Fillteán +Name[gl]=Cartafol +Name[he]=תיקייה +Name[hi]=फ़ोल्डर +Name[hr]=Mapa +Name[hu]=Könyvtár +Name[is]=Mappa +Name[it]=Cartella +Name[ja]=フォルダ +Name[ka]=საქაღალდე +Name[kk]=Қапшық +Name[km]=ថត +Name[ko]=홈 폴더 +Name[lt]=Aplankas +Name[lv]=Mape +Name[mk]=Папка +Name[mn]=хавтас +Name[mt]=Direttorju +Name[nb]=Mappe +Name[nds]=Orner +Name[ne]=फोल्डर +Name[nl]=Map +Name[nn]=Mappe +Name[pa]=ਫੋਲਡਰ +Name[pl]=Katalog +Name[pt]=Pasta +Name[pt_BR]=Pasta +Name[ru]=Папка +Name[rw]=Ububiko +Name[se]=Máhppa +Name[sk]=Priečinok +Name[sl]=Mapa +Name[sr]=Фасцикла +Name[sr@Latn]=Fascikla +Name[sv]=Katalog +Name[ta]=அடைவு +Name[te]=ఫొల్డర్ +Name[tg]=Феҳрист +Name[th]=โฟลเดอร์ +Name[tr]=Dizin +Name[tt]=Törgäk +Name[uk]=Тека +Name[uz]=Jild +Name[uz@cyrillic]=Жилд +Name[vi]=Thư mục +Name[wa]=Ridant +Name[zh_CN]=文件夹 +Name[zh_TW]=資料夾 +Open=false + +X-KDE-TreeModule=Directory +X-KDE-TreeModule-Lib=konq_sidebartree_dirtree +X-KDE-Default-URL=file:/ +X-KDE-TreeModule-ShowHidden=false diff --git a/konqueror/sidebar/trees/init/history.desktop b/konqueror/sidebar/trees/init/history.desktop new file mode 100644 index 000000000..f81c3a56f --- /dev/null +++ b/konqueror/sidebar/trees/init/history.desktop @@ -0,0 +1,164 @@ +[Desktop Entry] +Type=Link +URL= +Icon=history +Name=History +Name[af]=Geskiedenis +Name[ar]=الخطّ الزمني +Name[az]=Keçmiş +Name[be]=Гісторыя +Name[bg]=История +Name[bn]=ইতিহাস +Name[br]=Istor +Name[bs]=Historija +Name[ca]=Historial +Name[cs]=Historie +Name[csb]=Historëjô +Name[cy]=Hanes +Name[da]=Historik +Name[de]=Verlaufsspeicher +Name[el]=Ιστορικό +Name[eo]=Historio +Name[es]=Historial +Name[et]=Ajalugu +Name[eu]=Historia +Name[fa]=تاریخچه +Name[fi]=Historia +Name[fr]=Historique +Name[fy]=Histoarje +Name[ga]=Stair +Name[gl]=Historial +Name[he]=היסטוריה +Name[hi]=इतिहास +Name[hr]=Povijest +Name[hu]=Napló +Name[id]=Sejarah +Name[is]=Saga +Name[it]=Cronologia +Name[ja]=履歴 +Name[ka]=ისტორია +Name[kk]=Журнал +Name[km]=ប្រវត្តិ +Name[ko]=과거 기록 +Name[lo]=ປະວັດການໃຊ້ງານ +Name[lt]=Istorija +Name[lv]=Vēsture +Name[mk]=Историја +Name[mn]=Түүх +Name[ms]=Sejarah +Name[mt]=Kronoloġija +Name[nb]=Historie +Name[nds]=Vörgeschicht +Name[ne]=इतिहास +Name[nl]=Geschiedenis +Name[nn]=Historie +Name[nso]=Histori +Name[pa]=ਅਤੀਤ +Name[pl]=Historia +Name[pt]=Histórico +Name[pt_BR]=Histórico +Name[ro]=Istoric +Name[ru]=Журнал +Name[rw]=Amateka +Name[se]=Historihkka +Name[sk]=História +Name[sl]=Zgodovina +Name[sr]=Историјат +Name[sr@Latn]=Istorijat +Name[sv]=Historik +Name[ta]=வரலாறு +Name[te]=చరిత్ర +Name[tg]=Таърих +Name[th]=ประวัติการใช้ +Name[tr]=Geçmiş +Name[tt]=Taríx +Name[uk]=Історія +Name[uz]=Tarix +Name[uz@cyrillic]=Тарих +Name[ven]=Divhazwakale +Name[vi]=Lịch sử +Name[wa]=Istwere +Name[xh]=Imbali +Name[zh_CN]=历史 +Name[zh_TW]=歷史紀錄 +Name[zu]=Umlando +Comment=This is the history of the URLs you have recently visited. You can sort them in many ways. +Comment[af]=Hierdie is die geskiedenis van die Urls jy het onlangse besoekte. jy kan sorteer hulle in veel maniere. +Comment[ar]=هذا الخط الزمني للمواقع التي زرتها حديثاً. يمكنك ترتيبها بالعديد من الطرق. +Comment[az]=Bu da əvvəllər ziyarət etdiyiniz URLlərin siyahısıdır. Onları istədiyiniz kimi düzə bilərsiiz. +Comment[be]=Гэта гісторыя спасылак URL, якія вы раней наведалі. Вы можаце ўпарадкаваць іх рознымі спосабамі. +Comment[bg]=История на скоро посетените адреси +Comment[bn]=আপনি সম্প্রতি কোন কোন ইউ-আর-এল-এ গিয়েছেন তার ইতিহাস। আপনি এই তালিকাটি নানাভাবে সাজাতে পারেন। +Comment[bs]=Ovo je historija URLova koje ste nedavno posjetili. Možete ih složiti na više načina. +Comment[ca]=Aquest és l'historial amb els URL que heu visitat recentment. Podeu ordenar-les de moltes maneres. +Comment[cs]=Toto je historie URL, které jste naposledy navštívili. Můžete si je různými způsoby setřídit. +Comment[csb]=Historëjô slédno òbzérónëch adresów URL. Je mòżno jã na wszelejaczé ôrte zortowac. +Comment[cy]=Dyma hanes y safleoedd rydych wedi ymweld a nhw. Gallwch eu didoli mewn sawl ffordd. +Comment[da]=Dette er historikken for de URL'er du har besøgt for nyligt. Du kan sortere dem på mange måder. +Comment[de]=Dies ist ein Ordner für alle Adressen, die Sie in letzter Zeit besucht haben. Sie können sie auf vielerlei Weise sortieren. +Comment[el]=Αυτό είναι το ιστορικό των URL που επισκεφθήκατε πρόσφατα. Μπορείτε να τα ταξινομήσετε με πολλούς τρόπους. +Comment[eo]=Jen la historio de la vizititaj URLoj. Vi povas ordigi ilin diversmaniere. +Comment[es]=Este es el historial con las URLs que ha visitado recientemente. Puede ordenarlas de diversos modos. +Comment[et]=Sinu viimati külastatud saitide ajalugu. Ajalugu on võimalik mitmel moel sorteerida. +Comment[eu]=Hau bisitatu berri dituzun URLen historia da. Era askotan antola ditzakezu +Comment[fa]=این تاریخچۀ نشانیهای وبی است که اخیراً بازدید کردهاید. میتوانید آنها را به روشهای زیادی مرتب کنید. +Comment[fi]=Tämä on historia selatuista verkko-osoitteista. Ne voidaan järjestää monella tavalla. +Comment[fr]=Voici la liste des URL que vous avez récemment visitées. Vous pouvez les trier de multiples façons. +Comment[fy]=Dit is de histoarje fan de URL-adressen wêr jo koartlyn west ha. Jo kinne se op ferskate manieren sortearje. +Comment[gl]=Éste é o historial de URLs que visitou recentemente. Pode ordená-las de varios xeitos. +Comment[he]=זוהי היסטוריית הכתובות בהן ביקרת לאחרונה. באפשרותך לסדר אותה במגוון דרכים. +Comment[hi]=आप जो हालिया भ्रमण किए हैं, उन यूआरएल का यह इतिहास है. आप इन्हें कई तरीकों से क्रमबद्ध कर सकते हैं. +Comment[hr]=Povijest nedavno posjećenih URL adresa koji je moguće preslagivati na različite načine +Comment[hu]=Itt láthatók a legutóbb meglátogatott URL-ek. Többféle szempont szerint is sorba rendezhetők. +Comment[is]=Þetta er saga þeirra heimasíðna sem þú hefur heimsótt. Þú getur raðað þessum lista á ýmsan hátt. +Comment[it]=Questa è la cronologia degli indirizzi URL che hai visitato recentemente. Puoi ordinarli in vari modi. +Comment[ja]=最近訪問した URL のリストを表示します。リストはさまざまな方法でソートできます。 +Comment[ka]=ეს არის იმ URL-თა სია რომელიც ბოლო დროს მოინახულეთ. თქვენ შეგიძლიათ მათი დალაგება თქვენი ნებისამებრ +Comment[kk]=Жуырда жолыққан URL адрестер. Өз ыңғайыңызға қарай реттеп алуға болады. +Comment[km]=នេះជាប្រវត្តិរបស់ URL ដែលអ្នកបានទស្សនាថ្មីៗនេះ ។ អ្នកអាចតម្រៀបពួកវាតាមវិធីជាច្រើន ។ +Comment[ko]=이것은 최근에 방문한 URL 기록입니다. 다양한 방법으로 정렬할 수 있습니다. +Comment[lo]=ນີ້ເປັນປະວັດເກັບ URL ທີ່ທ່ານເຄີຍມມກ່ອນໂດຍທ່ານສາມາດລງງລຳດັບມັນໄດ້ໃນຫລາຍຮູບແບບ +Comment[lt]=Tai Jūsų neseniai aplankytų URL istorija, Jūs galite surūšiuoti juos įvairiais būdais. +Comment[lv]=Šī ir nesen apmeklēto URL vēsture. Jūs varat to šķirot daudzos veidos. +Comment[mk]=Ова е историја на URL кои скоро сте ги посетиле. Може да ги подредувате на разни начини. +Comment[mn]= Энэ бол таны хамгийн сүүлд айлчилсан URL хаягуудын түүх юм. Та тэдгээрийг янз бүрээр эрэмбэлж болно. +Comment[ms]=Ini ialah sejarah URL yang baru anda lawati. Anda tidak boleh isihkan ia dalam banyak cara. +Comment[mt]=Din hija kronoloġija tal-URLs kollha li żort reċentement. Tista' tissortjahom b'diversi modi. +Comment[nb]=Dette er en liste over de nettadressene du har vært innom nylig. Du kan sortere dem på ulike måter. +Comment[nds]=Dit is de Vörgeschicht vun Sieden, de Du tolest besöcht hest. Du kannst se op mennige Oorden sorteren. +Comment[ne]=यो तपाईँले भर्खरै अवलोकन गर्नु भएको यूआरएलहरूको सूची हो । तीनिहरूलाई तपाईँले धेरै तरिकाले क्रमबद्ध गर्न सक्नुहुन्छ । +Comment[nl]=Dit is de geschiedenis van de URL-adressen waar u recentelijk bent geweest. U kunt ze op meerdere manieren sorteren. +Comment[nn]=Dette er historia over adressene du nyleg har vitja. Du kan sortera lista på mange måtar. +Comment[nso]=Ye ke histori ya di-URL tseo odi etetsego gabjale. Okadi rarolla ka mekgwa ye mentshi. +Comment[pa]=ਇਹ URL ਦੀ ਸੂਚੀ ਹੈ, ਜੋ ਕਿ ਤੁਸੀਂ ਖੋਲੋ ਸਨ, ਤੁਸੀਂ ਇਹਨਾਂ ਨੂੰ ਕਈ ਤਰਾਂ ਕ੍ਰਮਬੱਧ ਕਰ ਸਕਦੇ ਹੋ। +Comment[pl]=Historia ostatnio odwiedzonych adresów URL. Można ją na różne sposoby posortować. +Comment[pt]=O histórico dos URLs visitados recentemente. É possível ordená-los de várias maneiras. +Comment[pt_BR]=Este é o histórico das URLs que você visitou recentemente. Você pode ordenar esta lista de várias maneiras. +Comment[ro]=Acesta este istoricul URL-urilor pe care le-ați vizitat recent. Le puteți sorta în diferite moduri. +Comment[ru]=Журнал недавно посещённых адресов (URL). Его можно настраивать по своему усмотрению. +Comment[rw]=Aya ni amateka ya URL wasuye vuba. Ushobora kuzishungura mu buryo bwinshi. +Comment[se]=Dán listtus oainnát čujuhusaid maid áiddo leat guossohan. Don sáhtát erohallat listtu máŋgga láhkai. +Comment[sk]=Toto je história URL, ktoré ste naposledy navštívili. Môžete ich utriediť rôznymi spôsobmi. +Comment[sl]=To je zgodovina URL-jev, ki ste jih pred kratkim obiskali. Lahko jih uredite na različne načine. +Comment[sr]=Ово је листа URL-ова које сте недавно посетили. Можете је поређати на разне начине. +Comment[sr@Latn]=Ovo je lista URL-ova koje ste nedavno posetili. Možete je poređati na razne načine. +Comment[sv]=Det här är historiken på de webbadresser du nyligen besökt. Du kan sortera dem på många sätt. +Comment[ta]=நீங்கள் தற்போது பார்த்த வலைப்பின்னல்களின் வரலாறு. அதை பல வழிகளில் வரிசைப்படுத்தலாம். +Comment[tg]=Ин саҳифаҳои аз торихчаи URL-ҳое ки охирон дидаед. Метавонед онҳоро ба ҳар сурати дархост мураттаб кунед. +Comment[th]=นี่เป็นประวัติเก็บ URL ที่คุณเคยไปมาก่อน โดยคุณสามารถเรียงลำดับมันได้ในหลายรูปแบบ +Comment[tr]=Bu sizim yakın geçmişte ziyaret ettiğiniz URL'lerin bir listesidir. Bunları bir çok şekilde sıralayabilirsiniz. +Comment[tt]=Soñğı arada qaralğan bulğan URL tezmäse. Anı törleçä tärtipläp bula. +Comment[uk]=Це - історія URL, які ви недавно відвідали. Ви можете також впорядкувати її будь-яким чином. +Comment[uz]=Yaqinda koʻrgan URL'larning tarixi. Ularni turlicha saralashingiz mumkin +Comment[uz@cyrillic]=Яқинда кўрган URL'ларнинг тарихи. Уларни турлича саралашингиз мумкин +Comment[ven]=Heyi ndi divhazwakale ya URL no i dalelaho zwazwino. Ni nga i lugisa nga ndila dzo fhambananho. +Comment[vi]=Đây là danh sách các URL bạn đã xem gần đây. Bạn có thể sắp xếp lại chúng theo vài cách khác nhau. +Comment[wa]=Cichal est l' istwere des URL ki vs avoz vizité enawaire. Vos les ploz arindjî di sacwantès manires. +Comment[xh]=Le yimbali yee URL obusandukuzindwendwela. Ungazibeka ngendlela ezininzi. +Comment[zh_CN]=这是您曾经浏览过的 URL 历史。您可以以多种方式对其排序。 +Comment[zh_TW]=這是您最近訪問的 URL 的歷史紀錄。您可以將它們以多種方式排序。 +Comment[zu]=Lo umlando wama-URL osanda kuwavakashela. Ungawahlela ngezindlela eziningi. +Open=false +X-KDE-TreeModule=History +X-KDE-SearchableTreeModule=true +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/history_module.desktop b/konqueror/sidebar/trees/init/history_module.desktop new file mode 100644 index 000000000..47d26b3b6 --- /dev/null +++ b/konqueror/sidebar/trees/init/history_module.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Type=Link +URL= +Icon=history +Name=History +Name[af]=Geskiedenis +Name[ar]=الخطّ الزمني +Name[az]=Keçmiş +Name[be]=Гісторыя +Name[bg]=История +Name[bn]=ইতিহাস +Name[br]=Istor +Name[bs]=Historija +Name[ca]=Historial +Name[cs]=Historie +Name[csb]=Historëjô +Name[cy]=Hanes +Name[da]=Historik +Name[de]=Verlaufsspeicher +Name[el]=Ιστορικό +Name[eo]=Historio +Name[es]=Historial +Name[et]=Ajalugu +Name[eu]=Historia +Name[fa]=تاریخچه +Name[fi]=Historia +Name[fr]=Historique +Name[fy]=Histoarje +Name[ga]=Stair +Name[gl]=Historial +Name[he]=היסטוריה +Name[hi]=इतिहास +Name[hr]=Povijest +Name[hu]=Napló +Name[id]=Sejarah +Name[is]=Saga +Name[it]=Cronologia +Name[ja]=履歴 +Name[ka]=ისტორია +Name[kk]=Журнал +Name[km]=ប្រវត្តិ +Name[ko]=과거 기록 +Name[lo]=ປະວັດການໃຊ້ງານ +Name[lt]=Istorija +Name[lv]=Vēsture +Name[mk]=Историја +Name[mn]=Түүх +Name[ms]=Sejarah +Name[mt]=Kronoloġija +Name[nb]=Historie +Name[nds]=Vörgeschicht +Name[ne]=इतिहास +Name[nl]=Geschiedenis +Name[nn]=Historie +Name[nso]=Histori +Name[pa]=ਅਤੀਤ +Name[pl]=Historia +Name[pt]=Histórico +Name[pt_BR]=Histórico +Name[ro]=Istoric +Name[ru]=Журнал +Name[rw]=Amateka +Name[se]=Historihkka +Name[sk]=História +Name[sl]=Zgodovina +Name[sr]=Историјат +Name[sr@Latn]=Istorijat +Name[sv]=Historik +Name[ta]=வரலாறு +Name[te]=చరిత్ర +Name[tg]=Таърих +Name[th]=ประวัติการใช้ +Name[tr]=Geçmiş +Name[tt]=Taríx +Name[uk]=Історія +Name[uz]=Tarix +Name[uz@cyrillic]=Тарих +Name[ven]=Divhazwakale +Name[vi]=Lịch sử +Name[wa]=Istwere +Name[xh]=Imbali +Name[zh_CN]=历史 +Name[zh_TW]=歷史紀錄 +Name[zu]=Umlando +Comment=This is the history of the URLs you have recently visited. You can sort them in many ways. +Comment[af]=Hierdie is die geskiedenis van die Urls jy het onlangse besoekte. jy kan sorteer hulle in veel maniere. +Comment[ar]=هذا الخط الزمني للمواقع التي زرتها حديثاً. يمكنك ترتيبها بالعديد من الطرق. +Comment[az]=Bu da əvvəllər ziyarət etdiyiniz URLlərin siyahısıdır. Onları istədiyiniz kimi düzə bilərsiiz. +Comment[be]=Гэта гісторыя спасылак URL, якія вы раней наведалі. Вы можаце ўпарадкаваць іх рознымі спосабамі. +Comment[bg]=История на скоро посетените адреси +Comment[bn]=আপনি সম্প্রতি কোন কোন ইউ-আর-এল-এ গিয়েছেন তার ইতিহাস। আপনি এই তালিকাটি নানাভাবে সাজাতে পারেন। +Comment[bs]=Ovo je historija URLova koje ste nedavno posjetili. Možete ih složiti na više načina. +Comment[ca]=Aquest és l'historial amb els URL que heu visitat recentment. Podeu ordenar-les de moltes maneres. +Comment[cs]=Toto je historie URL, které jste naposledy navštívili. Můžete si je různými způsoby setřídit. +Comment[csb]=Historëjô slédno òbzérónëch adresów URL. Je mòżno jã na wszelejaczé ôrte zortowac. +Comment[cy]=Dyma hanes y safleoedd rydych wedi ymweld a nhw. Gallwch eu didoli mewn sawl ffordd. +Comment[da]=Dette er historikken for de URL'er du har besøgt for nyligt. Du kan sortere dem på mange måder. +Comment[de]=Dies ist ein Ordner für alle Adressen, die Sie in letzter Zeit besucht haben. Sie können sie auf vielerlei Weise sortieren. +Comment[el]=Αυτό είναι το ιστορικό των URL που επισκεφθήκατε πρόσφατα. Μπορείτε να τα ταξινομήσετε με πολλούς τρόπους. +Comment[eo]=Jen la historio de la vizititaj URLoj. Vi povas ordigi ilin diversmaniere. +Comment[es]=Este es el historial con las URLs que ha visitado recientemente. Puede ordenarlas de diversos modos. +Comment[et]=Sinu viimati külastatud saitide ajalugu. Ajalugu on võimalik mitmel moel sorteerida. +Comment[eu]=Hau bisitatu berri dituzun URLen historia da. Era askotan antola ditzakezu +Comment[fa]=این تاریخچۀ نشانیهای وبی است که اخیراً بازدید کردهاید. میتوانید آنها را به روشهای زیادی مرتب کنید. +Comment[fi]=Tämä on historia selatuista verkko-osoitteista. Ne voidaan järjestää monella tavalla. +Comment[fr]=Voici la liste des URL que vous avez récemment visitées. Vous pouvez les trier de multiples façons. +Comment[fy]=Dit is de histoarje fan de URL-adressen wêr jo koartlyn west ha. Jo kinne se op ferskate manieren sortearje. +Comment[gl]=Éste é o historial de URLs que visitou recentemente. Pode ordená-las de varios xeitos. +Comment[he]=זוהי היסטוריית הכתובות בהן ביקרת לאחרונה. באפשרותך לסדר אותה במגוון דרכים. +Comment[hi]=आप जो हालिया भ्रमण किए हैं, उन यूआरएल का यह इतिहास है. आप इन्हें कई तरीकों से क्रमबद्ध कर सकते हैं. +Comment[hr]=Povijest nedavno posjećenih URL adresa koji je moguće preslagivati na različite načine +Comment[hu]=Itt láthatók a legutóbb meglátogatott URL-ek. Többféle szempont szerint is sorba rendezhetők. +Comment[is]=Þetta er saga þeirra heimasíðna sem þú hefur heimsótt. Þú getur raðað þessum lista á ýmsan hátt. +Comment[it]=Questa è la cronologia degli indirizzi URL che hai visitato recentemente. Puoi ordinarli in vari modi. +Comment[ja]=最近訪問した URL のリストを表示します。リストはさまざまな方法でソートできます。 +Comment[ka]=ეს არის იმ URL-თა სია რომელიც ბოლო დროს მოინახულეთ. თქვენ შეგიძლიათ მათი დალაგება თქვენი ნებისამებრ +Comment[kk]=Жуырда жолыққан URL адрестер. Өз ыңғайыңызға қарай реттеп алуға болады. +Comment[km]=នេះជាប្រវត្តិរបស់ URL ដែលអ្នកបានទស្សនាថ្មីៗនេះ ។ អ្នកអាចតម្រៀបពួកវាតាមវិធីជាច្រើន ។ +Comment[ko]=이것은 최근에 방문한 URL 기록입니다. 다양한 방법으로 정렬할 수 있습니다. +Comment[lo]=ນີ້ເປັນປະວັດເກັບ URL ທີ່ທ່ານເຄີຍມມກ່ອນໂດຍທ່ານສາມາດລງງລຳດັບມັນໄດ້ໃນຫລາຍຮູບແບບ +Comment[lt]=Tai Jūsų neseniai aplankytų URL istorija, Jūs galite surūšiuoti juos įvairiais būdais. +Comment[lv]=Šī ir nesen apmeklēto URL vēsture. Jūs varat to šķirot daudzos veidos. +Comment[mk]=Ова е историја на URL кои скоро сте ги посетиле. Може да ги подредувате на разни начини. +Comment[mn]= Энэ бол таны хамгийн сүүлд айлчилсан URL хаягуудын түүх юм. Та тэдгээрийг янз бүрээр эрэмбэлж болно. +Comment[ms]=Ini ialah sejarah URL yang baru anda lawati. Anda tidak boleh isihkan ia dalam banyak cara. +Comment[mt]=Din hija kronoloġija tal-URLs kollha li żort reċentement. Tista' tissortjahom b'diversi modi. +Comment[nb]=Dette er en liste over de nettadressene du har vært innom nylig. Du kan sortere dem på ulike måter. +Comment[nds]=Dit is de Vörgeschicht vun Sieden, de Du tolest besöcht hest. Du kannst se op mennige Oorden sorteren. +Comment[ne]=यो तपाईँले भर्खरै अवलोकन गर्नु भएको यूआरएलहरूको सूची हो । तीनिहरूलाई तपाईँले धेरै तरिकाले क्रमबद्ध गर्न सक्नुहुन्छ । +Comment[nl]=Dit is de geschiedenis van de URL-adressen waar u recentelijk bent geweest. U kunt ze op meerdere manieren sorteren. +Comment[nn]=Dette er historia over adressene du nyleg har vitja. Du kan sortera lista på mange måtar. +Comment[nso]=Ye ke histori ya di-URL tseo odi etetsego gabjale. Okadi rarolla ka mekgwa ye mentshi. +Comment[pa]=ਇਹ URL ਦੀ ਸੂਚੀ ਹੈ, ਜੋ ਕਿ ਤੁਸੀਂ ਖੋਲੋ ਸਨ, ਤੁਸੀਂ ਇਹਨਾਂ ਨੂੰ ਕਈ ਤਰਾਂ ਕ੍ਰਮਬੱਧ ਕਰ ਸਕਦੇ ਹੋ। +Comment[pl]=Historia ostatnio odwiedzonych adresów URL. Można ją na różne sposoby posortować. +Comment[pt]=O histórico dos URLs visitados recentemente. É possível ordená-los de várias maneiras. +Comment[pt_BR]=Este é o histórico das URLs que você visitou recentemente. Você pode ordenar esta lista de várias maneiras. +Comment[ro]=Acesta este istoricul URL-urilor pe care le-ați vizitat recent. Le puteți sorta în diferite moduri. +Comment[ru]=Журнал недавно посещённых адресов (URL). Его можно настраивать по своему усмотрению. +Comment[rw]=Aya ni amateka ya URL wasuye vuba. Ushobora kuzishungura mu buryo bwinshi. +Comment[se]=Dán listtus oainnát čujuhusaid maid áiddo leat guossohan. Don sáhtát erohallat listtu máŋgga láhkai. +Comment[sk]=Toto je história URL, ktoré ste naposledy navštívili. Môžete ich utriediť rôznymi spôsobmi. +Comment[sl]=To je zgodovina URL-jev, ki ste jih pred kratkim obiskali. Lahko jih uredite na različne načine. +Comment[sr]=Ово је листа URL-ова које сте недавно посетили. Можете је поређати на разне начине. +Comment[sr@Latn]=Ovo je lista URL-ova koje ste nedavno posetili. Možete je poređati na razne načine. +Comment[sv]=Det här är historiken på de webbadresser du nyligen besökt. Du kan sortera dem på många sätt. +Comment[ta]=நீங்கள் தற்போது பார்த்த வலைப்பின்னல்களின் வரலாறு. அதை பல வழிகளில் வரிசைப்படுத்தலாம். +Comment[tg]=Ин саҳифаҳои аз торихчаи URL-ҳое ки охирон дидаед. Метавонед онҳоро ба ҳар сурати дархост мураттаб кунед. +Comment[th]=นี่เป็นประวัติเก็บ URL ที่คุณเคยไปมาก่อน โดยคุณสามารถเรียงลำดับมันได้ในหลายรูปแบบ +Comment[tr]=Bu sizim yakın geçmişte ziyaret ettiğiniz URL'lerin bir listesidir. Bunları bir çok şekilde sıralayabilirsiniz. +Comment[tt]=Soñğı arada qaralğan bulğan URL tezmäse. Anı törleçä tärtipläp bula. +Comment[uk]=Це - історія URL, які ви недавно відвідали. Ви можете також впорядкувати її будь-яким чином. +Comment[uz]=Yaqinda koʻrgan URL'larning tarixi. Ularni turlicha saralashingiz mumkin +Comment[uz@cyrillic]=Яқинда кўрган URL'ларнинг тарихи. Уларни турлича саралашингиз мумкин +Comment[ven]=Heyi ndi divhazwakale ya URL no i dalelaho zwazwino. Ni nga i lugisa nga ndila dzo fhambananho. +Comment[vi]=Đây là danh sách các URL bạn đã xem gần đây. Bạn có thể sắp xếp lại chúng theo vài cách khác nhau. +Comment[wa]=Cichal est l' istwere des URL ki vs avoz vizité enawaire. Vos les ploz arindjî di sacwantès manires. +Comment[xh]=Le yimbali yee URL obusandukuzindwendwela. Ungazibeka ngendlela ezininzi. +Comment[zh_CN]=这是您曾经浏览过的 URL 历史。您可以以多种方式对其排序。 +Comment[zh_TW]=這是您最近訪問的 URL 的歷史紀錄。您可以將它們以多種方式排序。 +Comment[zu]=Lo umlando wama-URL osanda kuwavakashela. Ungawahlela ngezindlela eziningi. +Open=false +X-KDE-TreeModule=History +X-KDE-SearchableTreeModule=true +X-KDE-TreeModule-Lib=konq_sidebartree_history +X-KDE-Default-URL= diff --git a/konqueror/sidebar/trees/init/home.desktop b/konqueror/sidebar/trees/init/home.desktop new file mode 100644 index 000000000..d18f98466 --- /dev/null +++ b/konqueror/sidebar/trees/init/home.desktop @@ -0,0 +1,158 @@ +[Desktop Entry] +Type=Link +URL=file:$HOME +Icon=folder_home +Name=Home Folder +Name[af]=Tuis Gids +Name[ar]=منزلي +Name[az]=Ev Qovluğu +Name[be]=Хатняя тэчка +Name[bg]=Домашна директория +Name[bn]=ব্যক্তিগত ফোল্ডার +Name[br]=Renkell ar gêr +Name[bs]=Home direktorij +Name[ca]=Carpeta inici +Name[cs]=Domovská složka +Name[csb]=Domôcy katalog +Name[cy]=Plygell Cartref +Name[da]=Hjemmemappe +Name[de]=Persönlicher Ordner +Name[el]=Προσωπικός φάκελος +Name[eo]=Hejma dosierujo +Name[es]=Carpeta personal +Name[et]=Kodukataloog +Name[eu]=Etxeko karpeta +Name[fa]=پوشۀ آغازه +Name[fi]=Kotikansio +Name[fr]=Dossier personnel +Name[fy]=Persoanlike map +Name[ga]=Fillteán Baile +Name[gl]=Cartafol Persoal +Name[he]=תיקיית בית +Name[hi]=मुख फ़ोल्डर +Name[hr]=Početna mapa korisnika +Name[hu]=Saját könyvtár +Name[is]=Heimasvæði +Name[it]=Cartella Home +Name[ja]=ホームフォルダ +Name[ka]=საწყისი საქაღალდე +Name[kk]=Мекен қапшығы +Name[km]=ថតផ្ទះ +Name[ko]=홈 폴더 +Name[lt]=Namų aplankas +Name[lv]=Mājas mape +Name[mk]=Домашна папка +Name[mn]=Хувийн лавлах +Name[ms]=Folder Laman Utama +Name[mt]=Direttorju Personali +Name[nb]=Hjemmemappe +Name[nds]=Tohuus-Orner +Name[ne]=गृह फोल्डर +Name[nl]=Persoonlijke map +Name[nn]=Heimemappe +Name[pa]=ਘਰ ਫੋਲਡਰ +Name[pl]=Katalog domowy +Name[pt]=Pasta Pessoal +Name[pt_BR]=Pasta do Usuário +Name[ro]=Folder personal +Name[ru]=Домашняя папка +Name[rw]=Ububiko Urugo +Name[se]=Ruoktomáhppa +Name[sk]=Domovský priečinok +Name[sl]=Domača mapa +Name[sr]=Домаћа фасцикла +Name[sr@Latn]=Domaća fascikla +Name[sv]=Hemkatalog +Name[ta]=வீட்டு அடைவு +Name[te]=ఇంటి ఫొల్డర్ +Name[tg]=Феҳристи хонагӣ +Name[th]=โฟลเดอร์ส่วนตัว +Name[tr]=Başlangıç Dizini +Name[tt]=Ana Törgäk +Name[uk]=Домашня тека +Name[uz]=Uy jildi +Name[uz@cyrillic]=Уй жилди +Name[vi]=Thư mục Nhà +Name[wa]=Ridant måjhon +Name[zh_CN]=主文件夹 +Name[zh_TW]=家目錄 +Comment=This folder contains your personal files +Comment[af]=Hierdie kabinet bevat jou persoonlike lêers +Comment[ar]=هذا المجلّد يحتوي على ملفاتك الخاصة +Comment[az]=Bütün şəxsi fayllarınız bu qovluqda yer alır +Comment[be]=Гэтая тэчка ўтрымлівае вашы ўласныя файлы +Comment[bg]=Тази директория съдържа вашите лични файлове +Comment[bn]=এই ফোল্ডারে আপনার নিজের জাবতীয় ফাইল থাকে +Comment[bs]=Ovaj direktorij sadrži sve vaše osobne datoteke +Comment[ca]=Aquest directori conté els vostres fitxers personals +Comment[cs]=Tento adresář obsahuje vaše osobní soubory +Comment[csb]=Nen katalog zamëkô w se wszëtczé twòje priwatné lopczi +Comment[cy]=Mae'r plygell yma'n cadw eich ffeiliau personol +Comment[da]=Denne mappe indeholder dine personlige filer +Comment[de]=Dieser Ordner enthält Ihre persönlichen Dateien. +Comment[el]=Αυτός ο φάκελος περιέχει τα προσωπικά σας αρχεία +Comment[eo]=Tiu ĉi dosierujo enhavas viajn personajn dosierojn +Comment[es]=Esta carpeta contiene sus archivos personales +Comment[et]=See kataloog sisaldab sinu isiklike faile +Comment[eu]=Zeure fitxategiak karpeta honetan daude +Comment[fa]=این پوشه شامل پروندههای شخصی شماست +Comment[fi]=Tämä kansio sisältää henkilökohtaiset tiedostot +Comment[fr]=Ce dossier contient tous vos fichiers personnels +Comment[fy]=Dizze map befettet al jo persoanlike triemmen +Comment[ga]=Tá do chomhaid phearsanta san fhillteán seo +Comment[gl]=Este cartafol contén os seus ficheiros persoais +Comment[he]=תיקייה זו מכילה את הקבצים האישיים שלך +Comment[hi]=यह फ़ोल्डर आपकी निजी फ़ाइलें रखता है +Comment[hr]=Ova mapa sadrži vaše osobne datoteke +Comment[hu]=Ez a mappa tartalmazza az Ön személyes fájljait +Comment[is]=Þessi mappa inniheldur skjölin þín +Comment[it]=Questa cartella contiene i tuoi file personali +Comment[ja]=これはあなたの個人的なファイルを含むフォルダです +Comment[ka]=თქვენი პერსონალური ფაილების შესანახი საქაღალდე +Comment[kk]=Бұл қапшықта Сіздің дербес файлдарыңыз сақталады +Comment[km]=ថតនេះមានឯកសារផ្ទាល់ខ្លួនរបស់អ្នក +Comment[ko]=이 폴더는 개인 파일을 포함합니다 +Comment[lo]=ໂຟເດີນີ້ບັນຈຸແຟ້ມຕ່າງຯທີ່ເປັນສ່ວນຕົວຂອງທ່ານ +Comment[lt]=Šiame aplanke yra Jūsų asmeninės bylos +Comment[lv]=Šī mape satur jūsu personālos failus +Comment[mk]=Оваа папка ги содржи вашите лични датотеки +Comment[mn]=Энэ лавлах таны хувийн файлуудыг агуулна. +Comment[ms]=Folder ini mengandungi fail peribadi anda +Comment[mt]=Dan id-direttorju iżomm il-fajls personali kollha tiegħek. +Comment[nb]=Denne mappa inneholder dine personlige filer +Comment[nds]=In dissen Orner sünd dien egen Dateien +Comment[ne]=यो फोल्डरले तपाईँको व्यक्तिगत फाइलहरू समावेश गर्छ +Comment[nl]=Deze map bevat al uw persoonlijke bestanden +Comment[nn]=Denne mappa inneheld dine personlege filer. +Comment[nso]=Sephuthi se sena le difaele tsa gago tsa botho +Comment[pa]=ਇਹ ਫੋਲਡਰ ਤੁਹਾਡੀਆਂ ਨਿੱਜੀ ਫਾਇਲਾਂ ਰੱਖਦਾ ਹੈ +Comment[pl]=Ten katalog zawiera wszystkie twoje osobiste pliki. +Comment[pt]=Esta pasta contém os seus ficheiros pessoais +Comment[pt_BR]=Esta pasta contém os seus arquivos pessoais +Comment[ro]=Acest director conține fișierele dumneavoastră personale +Comment[ru]=Папка ваших личных файлов +Comment[rw]=Ubu bubiko bufite amadosiye yihariye yawe +Comment[se]=Dán máhpas du iežat fiillat leat +Comment[sk]=Tento priečinok obsahuje vaše osobné súbory +Comment[sl]=Ta mapa vsebuje vaše osebne datoteke. +Comment[sr]=Ова фасцикла садржи ваше личне фајлове +Comment[sr@Latn]=Ova fascikla sadrži vaše lične fajlove +Comment[sv]=Den här katalogen innehåller dina personliga filer +Comment[ta]=இந்த அடைவில் உங்கள் அந்தரங்க கோப்புகள் உள்ளன +Comment[tg]=Ин феҳрист шомили файлҳои шахсии шумост +Comment[th]=โฟลเดอร์นี้บรรจุแฟ้มต่าง ๆ ที่เป็นส่วนตัวของคุณ +Comment[tr]=Bu dizin kişisel dosyalarınızı içerir +Comment[tt]=Bu törgäktä şäxsi biremnäreñ yata +Comment[uk]=Ця тека містить ваші персональні файли +Comment[uz]=Bu jild sizning shaxsiy fayllaringizdan iborat +Comment[uz@cyrillic]=Бу жилд сизнинг шахсий файлларингиздан иборат +Comment[ven]=Foludara ino ina dzifaela dzanu +Comment[vi]=Thư mục này chứa các tập tin của riêng bạn +Comment[wa]=Ci ridant chal a les fitchîs et dnêyes da vosse +Comment[xh]=Le ncwadi eneenkcukacha iqulathe iifayile zobuntu bakho +Comment[zh_CN]=此文件夹包含了您的个人文件 +Comment[zh_TW]=這個資料夾包含有您的個人文件 +Comment[zu]=Lesi sigcini samafayela siqukethe amafayela akho siqu +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/remote.desktop b/konqueror/sidebar/trees/init/remote.desktop new file mode 100644 index 000000000..adc02b1cc --- /dev/null +++ b/konqueror/sidebar/trees/init/remote.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Name=Network +Name[af]=Netwerk +Name[ar]=الشبكة +Name[az]=Şəbəkə +Name[be]=Сетка +Name[bg]=Мрежа +Name[bn]=নেটওয়ার্ক +Name[br]=Rouedad +Name[bs]=Mreža +Name[ca]=Xarxa +Name[cs]=Síť +Name[csb]=Séc +Name[cy]=Rhwydwaith +Name[da]=Netværk +Name[de]=Netzwerk +Name[el]=Δίκτυο +Name[eo]=Reto +Name[es]=Red +Name[et]=Võrk +Name[eu]=Sarea +Name[fa]=شبکه +Name[fi]=Verkko +Name[fo]=Net +Name[fr]=Réseau +Name[fy]=Netwurk +Name[ga]=Líonra +Name[gl]=Rede +Name[he]=רשת +Name[hi]=नेटवर्क +Name[hr]=Mreža +Name[hu]=Hálózat +Name[id]=Jaringan +Name[is]=Net +Name[it]=Rete +Name[ja]=ネットワーク +Name[ka]=ქსელი +Name[kk]=Желі +Name[km]=បណ្ដាញ +Name[ko]=네트워크 +Name[lo]=ລະບົບເຄື່ອຄາຍ +Name[lt]=Tinklas +Name[lv]=Tīkls +Name[mk]=Мрежа +Name[mn]=Сүлжээ +Name[ms]=Rangkaian +Name[nb]=Nettverk +Name[nds]=Nettwark +Name[ne]=सञ्जाल +Name[nl]=Netwerk +Name[nn]=Nettverk +Name[nso]=Kgokagano +Name[oc]=Resèu +Name[pa]=ਨੈੱਟਵਰਕ +Name[pl]=Sieć +Name[pt]=Rede +Name[pt_BR]=Rede +Name[ro]=Rețea +Name[ru]=Сеть +Name[rw]=Urusobe +Name[se]=Fierbmi +Name[sk]=Sieť +Name[sl]=Omrežje +Name[sr]=Мрежа +Name[sr@Latn]=Mreža +Name[sv]=Nätverk +Name[ta]=வலைதளம் +Name[te]=నెట్ వర్క్ +Name[tg]=Шабака +Name[th]=ระบบเครือข่าย +Name[tr]=Ağ +Name[tt]=Çeltär +Name[uk]=Мережа +Name[uz]=Tarmoq +Name[uz@cyrillic]=Тармоқ +Name[ven]=Vhukwamani +Name[vi]=Mạng +Name[wa]=Rantoele +Name[xh]=Umsebenzi womnatha +Name[zh_CN]=网络 +Name[zh_TW]=網路 +Name[zu]=Uxhumano olusakazekile +Icon=network +Open=false +X-KDE-TreeModule=Virtual +X-KDE-RelURL=remote +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/remote/.directory b/konqueror/sidebar/trees/init/remote/.directory new file mode 100644 index 000000000..0f347fafb --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/.directory @@ -0,0 +1,84 @@ +[Desktop Entry] +Name=Network +Name[af]=Netwerk +Name[ar]=الشبكة +Name[az]=Şəbəkə +Name[be]=Сетка +Name[bg]=Мрежа +Name[bn]=নেটওয়ার্ক +Name[br]=Rouedad +Name[bs]=Mreža +Name[ca]=Xarxa +Name[cs]=Síť +Name[csb]=Séc +Name[cy]=Rhwydwaith +Name[da]=Netværk +Name[de]=Netzwerk +Name[el]=Δίκτυο +Name[eo]=Reto +Name[es]=Red +Name[et]=Võrk +Name[eu]=Sarea +Name[fa]=شبکه +Name[fi]=Verkko +Name[fo]=Net +Name[fr]=Réseau +Name[fy]=Netwurk +Name[ga]=Líonra +Name[gl]=Rede +Name[he]=רשת +Name[hi]=नेटवर्क +Name[hr]=Mreža +Name[hu]=Hálózat +Name[id]=Jaringan +Name[is]=Net +Name[it]=Rete +Name[ja]=ネットワーク +Name[ka]=ქსელი +Name[kk]=Желі +Name[km]=បណ្ដាញ +Name[ko]=네트워크 +Name[lo]=ລະບົບເຄື່ອຄາຍ +Name[lt]=Tinklas +Name[lv]=Tīkls +Name[mk]=Мрежа +Name[mn]=Сүлжээ +Name[ms]=Rangkaian +Name[nb]=Nettverk +Name[nds]=Nettwark +Name[ne]=सञ्जाल +Name[nl]=Netwerk +Name[nn]=Nettverk +Name[nso]=Kgokagano +Name[oc]=Resèu +Name[pa]=ਨੈੱਟਵਰਕ +Name[pl]=Sieć +Name[pt]=Rede +Name[pt_BR]=Rede +Name[ro]=Rețea +Name[ru]=Сеть +Name[rw]=Urusobe +Name[se]=Fierbmi +Name[sk]=Sieť +Name[sl]=Omrežje +Name[sr]=Мрежа +Name[sr@Latn]=Mreža +Name[sv]=Nätverk +Name[ta]=வலைதளம் +Name[te]=నెట్ వర్క్ +Name[tg]=Шабака +Name[th]=ระบบเครือข่าย +Name[tr]=Ağ +Name[tt]=Çeltär +Name[uk]=Мережа +Name[uz]=Tarmoq +Name[uz@cyrillic]=Тармоқ +Name[ven]=Vhukwamani +Name[vi]=Mạng +Name[wa]=Rantoele +Name[xh]=Umsebenzi womnatha +Name[zh_CN]=网络 +Name[zh_TW]=網路 +Name[zu]=Uxhumano olusakazekile +Icon=network +Open=false diff --git a/konqueror/sidebar/trees/init/remote/Makefile.am b/konqueror/sidebar/trees/init/remote/Makefile.am new file mode 100644 index 000000000..06c68f0cf --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = ftp web + +konq_sidebartree_virtuals_remote_data_DATA = .directory +konq_sidebartree_virtuals_remote_datadir = $(kde_datadir)/konqsidebartng/virtual_folders/remote diff --git a/konqueror/sidebar/trees/init/remote/ftp/.directory b/konqueror/sidebar/trees/init/remote/ftp/.directory new file mode 100644 index 000000000..75e432e50 --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/ftp/.directory @@ -0,0 +1,56 @@ +[Desktop Entry] +Name=FTP Archives +Name[az]=FTP Arxivləri +Name[bg]=FTP архиви +Name[br]=Dielloù FTP +Name[ca]=Arxius FTP +Name[cs]=FTP archívy +Name[csb]=Archiwa FTP +Name[cy]=Archif FTP +Name[da]=FTP-Arkiver +Name[de]=FTP-Archive +Name[el]=Αρχειοθήκες FTP +Name[eo]=FTP-Arkivoj +Name[es]=Archivos FTP +Name[et]=FTP-arhiivid +Name[fo]=FTP-søvn +Name[fr]=Archives FTP +Name[hi]=एफ़टीपी आर्काइव +Name[hr]=FTP arhive +Name[hu]=FTP +Name[id]=Arsip FTP +Name[is]=FTP gagnageymslur +Name[it]=Archivi FTP +Name[ja]=FTP アーカイブ +Name[km]=ប័ណ្ណសារ FTP +Name[ko]=FTP 저장소 +Name[lo]=ແຟ້ມບີບອັດ FTP +Name[lt]=FTP archyvai +Name[lv]=FTP Arhīvi +Name[mn]=FTP-Архив +Name[mt]=Arkivji FTP +Name[nb]=FTP-arkiv +Name[nds]=FTP-Archiven +Name[nl]=FTP-archieven +Name[nso]=Dipolokelo tsa FTP +Name[oc]=Archius FTP +Name[pl]=Archiwa FTP +Name[pt]=Arquivos de FTP +Name[pt_BR]=Arquivos de FTP +Name[ro]=Arhive FTP +Name[ru]=Серверы FTP +Name[sk]=FTP archívy +Name[sl]=Arhivi FTP +Name[sr]=FTP архиве +Name[sr@Latn]=FTP arhive +Name[sv]=FTP-arkiv +Name[tr]=FTP Arşivleri +Name[uk]=Архіви FTP +Name[uz]=FTP arxivlar +Name[uz@cyrillic]=FTP архивлар +Name[ven]=Fhethu huno vhulungwa zwa kale ha FTP +Name[wa]=Årtchives FTP +Name[xh]=Ushicilelo lukawonke-wonke kunye namanye amaxwebhu embali e FTP +Name[zh_TW]=FTP 歸檔 +Name[zu]=Imiqulu ye-FTP +Icon=konqueror diff --git a/konqueror/sidebar/trees/init/remote/ftp/Makefile.am b/konqueror/sidebar/trees/init/remote/ftp/Makefile.am new file mode 100644 index 000000000..c9a7c26aa --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/ftp/Makefile.am @@ -0,0 +1,3 @@ +konq_sidebartree_virtuals_remote_ftp_data_DATA = .directory kde_ftp.desktop +konq_sidebartree_virtuals_remote_ftp_datadir = $(kde_datadir)/konqsidebartng/virtual_folders/remote/ftp + diff --git a/konqueror/sidebar/trees/init/remote/ftp/kde_ftp.desktop b/konqueror/sidebar/trees/init/remote/ftp/kde_ftp.desktop new file mode 100644 index 000000000..3021fe215 --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/ftp/kde_ftp.desktop @@ -0,0 +1,88 @@ +[Desktop Entry] +Type=Link +URL=ftp://ftp.kde.org/pub/kde +Icon=ftp +Name=KDE Official FTP +Name[af]=Kde Amptelike Ftp +Name[ar]=ميفاق نقل الملفات الرسمي لِــ KDE +Name[az]=KDE FTP vericisi +Name[be]=Афіцыйны FTP KDE +Name[bg]=Официален FTP сървър на KDE +Name[bn]=মূল কে.ডি.ই. এফ.টি.পি. +Name[br]=FTP ofisiel KDE +Name[bs]=KDE službeni FTP +Name[ca]=FTP oficial del KDE +Name[cs]=Oficiální FTP projektu KDE +Name[csb]=Òficjalnô serwera FTP dlô KDE +Name[cy]=FTP Swyddogol KDE +Name[da]=KDE's officielle FTP +Name[de]=FTP-Bereich von KDE +Name[el]=Επίσημο FTP του KDE +Name[eo]=Oficiala FTP-arĥivo de KDE +Name[es]=FTP oficial de KDE +Name[et]=KDE ametlik FTP sait +Name[eu]=KDEren FTP ofiziala +Name[fa]=قاپ رسمی KDE +Name[fi]=KDE:n virallinen FTP +Name[fr]=Site FTP officiel de KDE +Name[fy]=KDE's Offisjele FTP +Name[ga]=FTP Oifigiúil KDE +Name[gl]=FTP Oficial de KDE +Name[he]=ה־FTP הרשמי של KDE +Name[hi]=केडीई आधिकारिक एफटीपी +Name[hr]=KDE službeni FTP +Name[hu]=Hivatalos KDE FTP +Name[id]=FTP KDE Resmi +Name[is]=FTP gagnabanki KDE +Name[it]=FTP ufficiale di KDE +Name[ja]=KDE 公式 FTP +Name[ka]=KDE-ს ძირითადი FTP სერვერი +Name[kk]=Негізгі KDE FTP сервері +Name[km]=FTP ផ្លូវការរបស់ KDE +Name[ko]=KDE 공식 FTP +Name[lo]=ໄຊ້์ FTP ຢ່າງເປັນທາງການຂອງ KDE +Name[lt]=KDE oficialus FTP +Name[lv]=KDE Oficiālais FTP +Name[mk]=Официјален FTP на KDE +Name[mn]=КДЭ-н FTP- хаяг +Name[ms]=FTP Rasmi KDE +Name[mt]=FTP Uffiċjali tal-KDE +Name[nb]=KDEs offisielle FTP +Name[nds]=Dat offizielle KDE-FTP +Name[ne]=KDE आधिकारिक FTP +Name[nl]=KDE's Officiële FTP +Name[nn]=Offisiell KDE-FTP +Name[nso]=FTP ya Semolao ya KDE +Name[oc]=FTP oficial dèu KDE +Name[pa]=KDE ਮੂਲ FTP +Name[pl]=Oficjalny serwer FTP dla KDE +Name[pt]=FTP Oficial do KDE +Name[pt_BR]=FTP oficial do KDE +Name[ro]=Site FTP KDE oficial +Name[ru]=Основной FTP-сервер KDE +Name[rw]=KDE FTP yemewe +Name[se]=Almmolaš KDE-FTP +Name[sk]=Oficiálne FTP KDE +Name[sl]=Uradni FTP za KDE +Name[sr]=Званични KDE-ов FTP +Name[sr@Latn]=Zvanični KDE-ov FTP +Name[sv]=KDE:s officiella FTP-server +Name[ta]=KDE அலுவலக FTP +Name[te]=కెడిఈ అధికారిక ఎఫ్ టి పి +Name[tg]=KDE расмии FTP +Name[th]=ไซต์ FTP ทางการของ KDE +Name[tr]=KDE FTP sunucusu +Name[tt]=KDE'nıñ Räsmi FTP +Name[uk]=Офіціальний FTP KDE +Name[uz]=Rasmiy KDE FTP +Name[uz@cyrillic]=Расмий KDE FTP +Name[ven]=FTP ya ofishiala ya KDE +Name[vi]=FTP chính thức của KDE +Name[wa]=Site FTP oficir di KDE +Name[xh]=KDE Osemthethweni FTP +Name[zh_CN]=KDE 官方 FTP +Name[zh_TW]=KDE 官方 FTP 站 +Name[zu]=I-FTP esemthethweni ye-KDE +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/remote/web/.directory b/konqueror/sidebar/trees/init/remote/web/.directory new file mode 100644 index 000000000..cb8fcc9a3 --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/web/.directory @@ -0,0 +1,56 @@ +[Desktop Entry] +Name=Web Sites +Name[az]=İnternet Saytları +Name[bg]=Уеб страници +Name[br]=Lec'hiennoù gwiad +Name[ca]=Llocs Web +Name[cs]=Webové stránky +Name[csb]=Starnë WWW +Name[cy]=Gwefannau +Name[da]=Netsteder +Name[de]=Webseiten +Name[el]=Τόποι στο διαδίκτυο +Name[eo]=Retejoj +Name[es]=Sitios web +Name[et]=Veebileheküljed +Name[fo]=Vevstøð +Name[fr]=Sites Web +Name[hi]=वेब साइट्स +Name[hr]=Web-lokacije +Name[hu]=Weboldalak +Name[id]=Situs Web +Name[is]=Vefsvæði +Name[it]=Siti web +Name[ja]=ウェブサイト +Name[km]=តំបន់បណ្ដាញ +Name[ko]=웹 사이트 +Name[lo]=ເວ໊ບໄຊ์ +Name[lt]=Žiniatinklio svetainės +Name[lv]=Tīmekļa vietas +Name[mn]=Вэб хуудсууд +Name[nb]=Nettsteder +Name[nds]=Nettsieden +Name[nl]=Websites +Name[nso]=Mafelo a Web +Name[oc]=Sitis web +Name[pl]=Strony WWW +Name[pt]=Páginas Web +Name[pt_BR]=Páginas Web +Name[ro]=Sit-uri de Web +Name[ru]=Веб-сайты +Name[sk]=Webové stránky +Name[sl]=Spletne strani +Name[sr]=Веб сајтови +Name[sr@Latn]=Veb sajtovi +Name[sv]=Webbplatser +Name[tg]=Саҳифаҳои Веб +Name[tr]=Web Siteleri +Name[uk]=Веб-сайти +Name[uz]=Veb-saytlar +Name[uz@cyrillic]=Веб-сайтлар +Name[ven]=Webu saiti +Name[wa]=Sites waibes +Name[xh]=Amanxuwa e Web +Name[zh_TW]=網站 +Name[zu]=Iziza ze-Web +Icon=konqueror diff --git a/konqueror/sidebar/trees/init/remote/web/Makefile.am b/konqueror/sidebar/trees/init/remote/web/Makefile.am new file mode 100644 index 000000000..30bc162b6 --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/web/Makefile.am @@ -0,0 +1,2 @@ +konq_sidebartree_virtuals_remote_web_data_DATA = .directory apps_web.desktop dot_web.desktop kde_web.desktop look_web.desktop +konq_sidebartree_virtuals_remote_web_datadir = $(kde_datadir)/konqsidebartng/virtual_folders/remote/web diff --git a/konqueror/sidebar/trees/init/remote/web/apps_web.desktop b/konqueror/sidebar/trees/init/remote/web/apps_web.desktop new file mode 100644 index 000000000..694c4a04f --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/web/apps_web.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Type=Link +URL=http://www.kde-apps.org/ +Name=KDE Applications +Name[af]=Kde Programme +Name[ar]=تطبيقات KDE +Name[az]=KDE Proqramları +Name[be]=Праграмы KDE +Name[bg]=Програми за KDE +Name[bn]=কে.ডি.ই অ্যাপলিকেশন +Name[br]=Arloadoù KDE +Name[bs]=KDE Programi +Name[ca]=Aplicacions KDE +Name[cs]=KDE aplikace +Name[csb]=Programë KDE +Name[cy]=Cymhwysiadau KDE +Name[da]=KDE-programmer +Name[de]=KDE-Programme +Name[el]=Εφαρμογές KDE +Name[eo]=KDE-Aplikaĵoj +Name[es]=Aplicaciones de KDE +Name[et]=KDE rakendused +Name[eu]=KDEren aplikazioak +Name[fa]=کاربردهای KDE +Name[fi]=KDE:n sovellukset +Name[fr]=Applications KDE +Name[fy]=KDE Programma's +Name[ga]=Feidhmchláir KDE +Name[gl]=Aplicacións de KDE +Name[he]=יישומי KDE +Name[hi]=केडीई अनुप्रयोग +Name[hr]=KDE aplikacije +Name[hu]=KDE-alkalmazások +Name[is]=KDE Forrit +Name[it]=Applicazioni KDE +Name[ja]=KDE アプリケーション +Name[ka]=KDE-ს პროგრამები +Name[kk]=KDE қолданбалары +Name[km]=កម្មវិធីរបស់ KDE +Name[ko]=KDE 응용 프로그램 +Name[lo]=ແອບພີເຄຊັ້ນ KDE +Name[lt]=KDE programos +Name[lv]=KDE Aplikācijas +Name[mk]=KDE-апликации +Name[mn]=КДЭ-Програм +Name[ms]=Aplikasi KDE +Name[mt]=Programmi KDE +Name[nb]=KDE-programmer +Name[nds]=KDE-Programmen +Name[ne]=KDE अनुप्रयोग +Name[nl]=KDE Programma's +Name[nn]=KDE-program +Name[nso]=Ditshomiso tsa KDE +Name[pa]=KDE ਕਾਰਜ +Name[pl]=Programy KDE +Name[pt]=Aplicações do KDE +Name[pt_BR]=Aplicativos KDE +Name[ro]=Aplicații KDE +Name[ru]=Приложения KDE +Name[rw]=Porogaramu KDE +Name[se]=KDE-prográmmat +Name[sk]=Aplikácie KDE +Name[sl]=Uporabniški programi +Name[sr]=KDE програми +Name[sr@Latn]=KDE programi +Name[ss]=Ticelo te KDE +Name[sv]=KDE-program +Name[ta]=KDE நிரல்கள் +Name[te]=కెడిఈ కార్యక్రమాలు +Name[tg]=Барномаҳои KDE +Name[th]=แอพพลิเคชัน KDE +Name[tr]=KDE Uygulamaları +Name[tt]=KDE Yazılımnarı +Name[uk]=Програми KDE +Name[uz]=KDE dasturlar +Name[uz@cyrillic]=KDE дастурлар +Name[ven]=Apulifikhesheni ya KDE +Name[vi]=Ứng dụng cho KDE +Name[wa]=Programes KDE +Name[xh]=Izicelo ze KDE +Name[zh_CN]=KDE 应用程序 +Name[zh_TW]=KDE 應用程式 +Name[zu]=Abayaleli be-KDE +Icon=www +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/remote/web/dot_web.desktop b/konqueror/sidebar/trees/init/remote/web/dot_web.desktop new file mode 100644 index 000000000..9743376df --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/web/dot_web.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Type=Link +URL=http://dot.kde.org/ +Name=KDE News +Name[af]=Kde Nuus +Name[ar]=أخبار KDE +Name[az]=KDE Xəbərləri +Name[be]=Навіны KDE +Name[bg]=Новини за KDE +Name[bn]=কে.ডি.ই. সংবাদ +Name[br]=Keleier KDE +Name[bs]=KDE Novosti +Name[ca]=Notícies KDE +Name[cs]=Novinky KDE +Name[csb]=Nowinë KDE +Name[cy]=Newyddion KDE +Name[da]=KDE-nyheder +Name[de]=KDE-Nachrichten +Name[el]=Νέα KDE +Name[eo]=KDE-Novaĵoj +Name[es]=Noticias de KDE +Name[et]=KDE uudised +Name[eu]=KDEren albisteak +Name[fa]=اخبار KDE +Name[fi]=KDE:n uutiset +Name[fr]=Les nouvelles sur KDE +Name[fy]=KDE Nijs +Name[ga]=Nuacht KDE +Name[gl]=Novas de KDE +Name[he]=חדשות KDE +Name[hi]=केडीई समाचार +Name[hr]=KDE novosti +Name[hu]=KDE hírek +Name[is]=KDE fréttir +Name[it]=Notizie di KDE +Name[ja]=KDE ニュース +Name[ka]=KDE-ს სიახლეები +Name[kk]=KDE жаңалықтары +Name[km]=ព័ត៌មាន KDE +Name[ko]=KDE 뉴스 +Name[lo]=ຂ່າວຂອງ KDE +Name[lt]=KDE naujienos +Name[lv]=KDE Ziņas +Name[mk]=KDE-вести +Name[mn]=КДЭ-Мэдээ +Name[ms]=Berita KDE +Name[mt]=Aħbarijiet KDE +Name[nb]=KDE-nyheter +Name[nds]=KDE-Narichten +Name[ne]=KDE समाचार +Name[nl]=KDE Nieuws +Name[nn]=KDE-nyhende +Name[nso]=Ditaba tsa KDE +Name[pa]=KDE ਖ਼ਬਰਾਂ +Name[pl]=Wiadomości KDE +Name[pt]=Notícias do KDE +Name[ro]=Știri KDE +Name[ru]=Новости KDE +Name[rw]=KDE Amakuru +Name[se]=KDE-ođđasat +Name[sk]=Novinky KDE +Name[sl]=Novice o KDE +Name[sr]=KDE вести +Name[sr@Latn]=KDE vesti +Name[ss]=Tindzaba te KDE +Name[sv]=KDE-nyheter +Name[ta]=KDE செய்திகள் +Name[te]=కెడిఈ వార్తలు +Name[tg]=Иттилоотҳои KDE +Name[th]=ข่าวของ KDE +Name[tr]=KDE Haberleri +Name[tt]=KDE Yañalıqları +Name[uk]=Новини KDE +Name[uz]=KDE yangiliklar +Name[uz@cyrillic]=KDE янгиликлар +Name[ven]=Mafhungo a KDE +Name[vi]=Tin tức KDE +Name[wa]=Noveles di KDE +Name[xh]=Iindaba ze KDE +Name[zh_CN]=KDE 新闻 +Name[zh_TW]=KDE 新聞 +Name[zu]=Izindaba ze-KDE +Icon=www +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/remote/web/kde_web.desktop b/konqueror/sidebar/trees/init/remote/web/kde_web.desktop new file mode 100644 index 000000000..4228c0b48 --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/web/kde_web.desktop @@ -0,0 +1,88 @@ +[Desktop Entry] +Type=Link +URL=http://www.kde.org +Name=KDE Home Page +Name[af]=KDE Tuisblad +Name[ar]=موقع KDE على الشبكة +Name[az]=KDE Ana Səhifəsi +Name[be]=Хатняя старонка KDE +Name[bg]=Домашна страница на KDE +Name[bn]=কে.ডি.ই. হোম পেজ +Name[br]=Pajenn Er-Gêr KDE +Name[bs]=KDE web stranica +Name[ca]=Pàgina inici de KDE +Name[cs]=Domovská stránka KDE +Name[csb]=Domôcô starna KDE +Name[cy]=Hafan KDE +Name[da]=KDE-hjemmeside +Name[de]=KDE-Startseite +Name[el]=Ιστοσελίδα του KDE +Name[eo]=TTTejo de KDE +Name[es]=Página Web de KDE +Name[et]=KDE kodulehekülg +Name[eu]=KDEren hasierako orria +Name[fa]=صفحه آغازۀ KDE +Name[fi]=KDE:n kotisivu +Name[fr]=Page d'accueil de KDE +Name[fy]=KDE's Thússide +Name[ga]=Leathanach Baile KDE +Name[gl]=Páxina Web de KDE +Name[he]=אתר הבית של KDE +Name[hi]=केडीई मुख पृष्ठ +Name[hr]=KDE glavna stranica +Name[hu]=KDE honlap +Name[id]=Home Page KDE +Name[is]=Heimasíða KDE +Name[it]=Homepage di KDE +Name[ja]=KDE ホームページ +Name[ka]=KDE-ს ვებ გვერდი +Name[kk]=KDE веб-сайты +Name[km]=គេហទំព័រ KDE +Name[ko]=KDE 홈페이지 +Name[lo]=ໂຫມເພຈ KDE +Name[lt]=KDE namų puslapis +Name[lv]=KDE Mājas Lapa +Name[mk]=Домашната страница на KDE +Name[mn]=КДЭ-Эхлэл хуудас +Name[ms]=Laman Utama KDE +Name[mt]=Homepage tal-KDE +Name[nb]=KDEs hjemmeside +Name[nds]=KDE-Nettsiet +Name[ne]=KDE गृह पृष्ठ +Name[nl]=KDE's startpagina +Name[nn]=KDE-nettstaden +Name[nso]=Letlakala la Gae la KDE +Name[oc]=Pagina iniciau de KDE +Name[pa]=KDE ਮੁੱਖ ਸਫਾ +Name[pl]=Strona domowa KDE +Name[pt]=Página do KDE +Name[pt_BR]=Página principal do KDE +Name[ro]=Site-ul KDE +Name[ru]=Основной сайт KDE +Name[rw]=KDE Ipajikwinjira +Name[se]=KDE-ruoktosiidu +Name[sk]=Domovská stránka KDE +Name[sl]=Domača stran KDE +Name[sr]=Матична страна KDE-а +Name[sr@Latn]=Matična strana KDE-a +Name[sv]=KDE:s webbplats +Name[ta]=KDE வீட்டுப் பக்கம் +Name[te]=కెడిఈ ఇంటి పుట +Name[tg]=Сафҳаи хонагии KDE +Name[th]=โฮมเพจ KDE +Name[tr]=KDE Ana Sayfası +Name[tt]=KDE Anabite +Name[uk]=Домашня сторінка KDE +Name[uz]=KDE veb-sayti +Name[uz@cyrillic]=KDE веб-сайти +Name[ven]=Siatari la KDE +Name[vi]=Trang nhà của KDE +Name[wa]=Pådje måjhon di KDE +Name[xh]=Iphepha Lasekhaya le KDE +Name[zh_CN]=KDE 主页 +Name[zh_TW]=KDE 首頁 +Name[zu]=Ikhasi lasekhaya le-KDE +Icon=www +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/remote/web/look_web.desktop b/konqueror/sidebar/trees/init/remote/web/look_web.desktop new file mode 100644 index 000000000..eadd73827 --- /dev/null +++ b/konqueror/sidebar/trees/init/remote/web/look_web.desktop @@ -0,0 +1,54 @@ +[Desktop Entry] +Type=Link +URL=http://themes.kde.org/ +Name=KDE Eye Candy +Name[af]=KDE Oog genot +Name[bn]=কে.ডি.ই. আই ক্যান্ডি +Name[bs]=KDE ukrasi +Name[ca]=Decoració KDE +Name[cs]=Pastva pro oči +Name[csb]=Ùsnôżnienia dlô KDE +Name[da]=KDE øjenfryd +Name[de]=KDE Optik +Name[el]=KDE Εμφάνιση +Name[eo]=KDE Ornamaĵoj +Name[es]=Embellecimiento KDE +Name[et]=KDE silmailu +Name[fi]=KDE:n silmän iloa +Name[fr]=Agrément visuel KDE +Name[fy]=Eachstrieljende KDE +Name[gl]=Embelecemento de KDE +Name[he]=צעצועים חזותיים של KDE +Name[hr]=KDE mamac za oko +Name[hu]=KDE grafikai kiegészítők +Name[is]=KDE augnayndi +Name[it]=Bellezza di KDE +Name[ja]=KDE アイキャンディ +Name[km]=ទិដ្ឋភាពស្រស់ស្អាតរបស់ KDE +Name[ko]=KDE 눈깔사탕 +Name[mk]=Убавина за очи во KDE +Name[nb]=KDE-pynt +Name[nds]=Wat för de Ogen vun KDE +Name[ne]=KDE आइ क्यान्डी +Name[nl]=Oogstrelend KDE +Name[nn]=KDE-pynt +Name[pa]=KDE ਆਈ ਕੈਂਡੀ +Name[pl]=Upiększenia dla KDE +Name[pt]=Gráficos Bonitos do KDE +Name[pt_BR]=Candy Eye do KDE +Name[ro]=Tematici KDE +Name[ru]=Темы и стили для KDE +Name[se]=KDE-čalbmenjálgát +Name[sl]=Bombončki KDE +Name[sr]=KDE слаткиши +Name[sr@Latn]=KDE slatkiši +Name[sv]=KDE-ögongodis +Name[ta]=கேடியி ஐ காண்டி +Name[th]=ตกแต่งน่ารักกับ KDE +Name[vi]=Kẹo ngọt Thị giác KDE +Name[wa]=KDE bea po ls ouys +Name[zh_CN]=KDE 眼福 +Icon=www +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/root.desktop b/konqueror/sidebar/trees/init/root.desktop new file mode 100644 index 000000000..b206da8e7 --- /dev/null +++ b/konqueror/sidebar/trees/init/root.desktop @@ -0,0 +1,158 @@ +[Desktop Entry] +Type=Link +URL=file:/ +Icon=folder_red +Name=Root Folder +Name[af]=Basis Gids +Name[ar]=مجلد الجذر +Name[az]=Ali İstifadəçi Qovluğu +Name[be]=Каранёвая тэчка +Name[bg]=Главна директория +Name[bn]=রুট ফোল্ডার +Name[br]=Renkell gwrizienn +Name[bs]=Root direktorij +Name[ca]=Carpeta arrel +Name[cs]=Kořenová složka +Name[csb]=Przédny katalog (root) +Name[cy]=Plygell Gwraidd +Name[da]=Rodmappe +Name[de]=Basisordner +Name[el]=Ριζικός φάκελος +Name[eo]=Baza dosierujo +Name[es]=Directorio raiz +Name[et]=Juurkataloog +Name[eu]=Erro karpeta +Name[fa]=پوشۀ ریشه +Name[fi]=Juurikansio +Name[fr]=Dossier racine +Name[fy]=Haadmap +Name[ga]=Fréamhfhillteán +Name[gl]=Cartafol Raíz +Name[he]=תיקיית שורש +Name[hi]=रूट फ़ोल्डर +Name[hr]=Korijenska mapa +Name[hu]=Gyökérkönyvtár +Name[is]=Rótarmappa +Name[it]=Cartella radice +Name[ja]=ルートフォルダ +Name[ka]=ძირეული საქაღალდე +Name[kk]=Түбір қапшығы +Name[km]=ថត Root +Name[ko]=루트 폴더 +Name[lt]=Root aplankas +Name[lv]=Saknes katalogs +Name[mk]=Коренова папка +Name[mn]=Язгуур лавлах +Name[ms]=Folder Root +Name[mt]=Direttorju root +Name[nb]=Rotkatalog +Name[nds]=Wörtelorner +Name[ne]=रुट फोल्डर +Name[nl]=Hoofdmap +Name[nn]=Rotmappe +Name[pa]=ਰੂਟ(root) ਫੋਲਡਰ +Name[pl]=Katalog główny +Name[pt]=Pasta Raiz +Name[pt_BR]=Pasta Raiz +Name[ro]=Folder rădăcină +Name[ru]=Корневая папка +Name[rw]=Ububiko Umuzi +Name[se]=Ruohtasmáhppa +Name[sk]=Koreňový priečinok +Name[sl]=Korenska mapa +Name[sr]=Корена фасцикла +Name[sr@Latn]=Korena fascikla +Name[sv]=Rotkatalog +Name[ta]=ஆரம்ப அடைவு +Name[te]=రూట్ ఫొల్డర్ +Name[tg]=Феҳристи реша +Name[th]=โฟลเดอร์ราก +Name[tr]=Kök Dizini +Name[tt]=Töp Törgäk +Name[uk]=Коренева тека +Name[uz]=Tub jildi +Name[uz@cyrillic]=Туб жилди +Name[vi]=Thư mục Gốc +Name[wa]=Ridant raecene +Name[zh_CN]=根文件夹 +Name[zh_TW]=Root 資料夾 +Comment=This is the root of the filesystem +Comment[af]=Hierdie is die basis van die lêer stelsel +Comment[ar]=هذا هو الجذر لنظام الملفات +Comment[az]=Bu, fayl sisteminizin köküdür +Comment[be]=Гэта пачатак файлавай сістэмы +Comment[bg]=Тази директория е главната директория на системата +Comment[bn]=এটি ফাইলসিস্টেমের মূল (root) +Comment[bs]=Ovo je korijen datotečnog sistema +Comment[ca]=Aquest és l'arrel del sistema de fitxers +Comment[cs]=Toto je kořenový adresář souborového systému +Comment[csb]=Je to kòrzéń systemë lopków (przédny katalog - root) +Comment[cy]=Dyma wraidd y cysawd ffeiliau +Comment[da]=Dette er roden af filsystemet +Comment[de]=Dies ist der Basisordner Ihres Dateisystems +Comment[el]=Αυτή είναι η ρίζα του συστήματος αρχείων +Comment[eo]=Jen la radiko de la dosieraro +Comment[es]=Esta es la raíz del sistema de archivos +Comment[et]=See on failisüsteemi ülemkataloog +Comment[eu]=Hau fitxategi sistemaren erroa da +Comment[fa]=این ریشه سیستم پرونده است +Comment[fi]=Tämä on tiedostojärjestelmän juuri +Comment[fr]=Ce dossier est à la racine de votre arborescence +Comment[fy]=Dit is de haad fan it triemsysteem +Comment[ga]=Seo fréamh an comhadchórais +Comment[gl]=Ésta é a raiz do sistema de arquivos +Comment[he]=זהו השורש של מערכת הקבצים שלך +Comment[hi]=यह फ़ाइल सिस्टम का रूट है +Comment[hr]=Korijenska mapa datotečnog sustava +Comment[hu]=Ez a fájlrendszer gyökere +Comment[is]=Þetta er rót skráarkerfisins +Comment[it]=Questa è la radice del filesystem +Comment[ja]=ファイルシステムのルートです +Comment[ka]=ფაილური სისტემუს ძირეული საქაღალდე +Comment[kk]=Файл жүйесінің түбірі +Comment[km]=នេះជាឫសរបស់ប្រព័ន្ធឯកសារ +Comment[ko]=파일 시스템의 루트입니다 +Comment[lo]=ນີ້ເປັນຮາກຂອງລະບົບແຟ້ມ +Comment[lt]=Tai yra bylų sistemos pradžia +Comment[lv]=Šī ir failusistēmas sakne +Comment[mk]=Ова е коренот на датотечниот системот +Comment[mn]=Энэ бол таны файлын системийн язгуур +Comment[ms]=Ini ialah root bagi sistem fail +Comment[mt]=Dan huwa d-direttorju ewlieni tas-sistema +Comment[nb]=Dette er rota til filsystemet +Comment[nds]=Dit is dat Dateisysteem sien Wörtel +Comment[ne]=यो फाइल प्रणालीको रुट हो +Comment[nl]=Dit is de root van het bestandssysteem +Comment[nn]=Dette er rota i filsystemet. +Comment[nso]=Se ke modu wa system ya faele +Comment[pa]=ਇਹ ਫਾਇਲ ਸਿਸਟਮ ਦਾ ਰੂਟ (root) ਹੈ +Comment[pl]=To jest korzeń systemu plików (czyli katalog główny) +Comment[pt]=Este é o topo do sistema de ficheiros +Comment[pt_BR]=Esta é a raiz do seu sistema de arquivos +Comment[ro]=Aceasta este rădăcina sistemului de fișiere +Comment[ru]=Корневая папка файловой системы +Comment[rw]=Uyu ni umuzi w'idosiyesisitemu +Comment[se]=Dát lea du fiilavuogádaga ruohtas +Comment[sk]=Toto je koreňový priečinok systému súborov +Comment[sl]=To je koren datotečnega sistema. +Comment[sr]=Ово је корен система фајлова +Comment[sr@Latn]=Ovo je koren sistema fajlova +Comment[sv]=Det här är roten på filsystemet +Comment[ta]=இதுவே கோப்பு அமைப்பின் வேராகும் +Comment[tg]=Инҷо решаи системаи файл аст +Comment[th]=นี่เป็นรากของระบบแฟ้ม +Comment[tr]=Bu dosya sisteminizi kök dizinidir +Comment[tt]=Birem sistemeneñ töp törgäge bu +Comment[uk]=Це - корінь файлової системи +Comment[uz]=Fayl tizimining tubi +Comment[uz@cyrillic]=Файл тизимининг туби +Comment[ven]=Hoyu ndi mudzi wa maitele a faela +Comment[vi]=Đây là gốc của hệ thống tập tin +Comment[wa]=Cichal est li ridant raecene do sistinme di fitchîs +Comment[xh]=Le yingcambu yendlela yefayile +Comment[zh_CN]=这是文件系统的根 +Comment[zh_TW]=這是檔案系統的根目錄 +Comment[zu]=Le yimpande yesistimu yamafayela +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/services.desktop b/konqueror/sidebar/trees/init/services.desktop new file mode 100644 index 000000000..72c51db89 --- /dev/null +++ b/konqueror/sidebar/trees/init/services.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +URL= +Icon=services +Name=Services +Name[af]=Dienste +Name[ar]=الخدمات +Name[az]=Xidmətlər +Name[be]=Сервісы +Name[bg]=Услуги +Name[bn]=সার্ভিসসমূহ +Name[br]=Servijoù +Name[bs]=Servisi +Name[ca]=Serveis +Name[cs]=Služby +Name[csb]=Ùsłëżnotë +Name[cy]=Gwasanaethau +Name[da]=Tjenester +Name[de]=KDE-Dienste +Name[el]=Υπηρεσίες +Name[eo]=Servoj +Name[es]=Servicios +Name[et]=Teenused +Name[eu]=Zerbitzuak +Name[fa]=خدمات +Name[fi]=Palvelut +Name[fo]=Tænastur +Name[fy]=Tsjinsten +Name[ga]=Seirbhísí +Name[gl]=Servizos +Name[he]=שירותים +Name[hi]=सेवाएं +Name[hr]=Usluge +Name[hu]=Szolgáltatások +Name[is]=Þjónustur +Name[it]=Servizi +Name[ja]=サービス +Name[ka]=სერვისები +Name[kk]=Қызметтер +Name[km]=សេវា +Name[ko]=서비스 +Name[lo]=ບໍລິການ +Name[lt]=Tarnybos +Name[lv]=Servisi +Name[mk]=Сервиси +Name[mn]=КДЭ-Үйлчилгээ +Name[ms]=Servis +Name[mt]=Servizzi +Name[nb]=Tjenester +Name[nds]=KDE-Deensten +Name[ne]=सेवा +Name[nn]=Tenester +Name[nso]=Ditirelo +Name[pa]=ਸੇਵਾਵਾਂ +Name[pl]=Usługi +Name[pt]=Serviços +Name[pt_BR]=Serviços +Name[ro]=Servicii +Name[ru]=Сервисы +Name[rw]=Serivise +Name[se]=Bálvalusat +Name[sk]=Služby +Name[sl]=Storitve +Name[sr]=Сервиси +Name[sr@Latn]=Servisi +Name[sv]=Tjänster +Name[ta]=சேவைகள் +Name[te]=సేవలు +Name[tg]=Хидматҳо +Name[th]=บริการ +Name[tr]=Servisler +Name[tt]=Xezmätlär +Name[uk]=Служби +Name[uz]=Xizmatlar +Name[uz@cyrillic]=Хизматлар +Name[ven]=Dzitshumelo +Name[vi]=Các dịch vụ +Name[wa]=Siervices +Name[xh]=Iinkonzo +Name[zh_CN]=服务 +Name[zh_TW]=服務 +Name[zu]=Imisebenzi +Open=false +X-KDE-TreeModule=Virtual +X-KDE-RelURL=services +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/services/.directory b/konqueror/sidebar/trees/init/services/.directory new file mode 100644 index 000000000..7d2b5e78c --- /dev/null +++ b/konqueror/sidebar/trees/init/services/.directory @@ -0,0 +1,81 @@ +[Desktop Entry] +Icon=pipe +Name=Services +Name[af]=Dienste +Name[ar]=الخدمات +Name[az]=Xidmətlər +Name[be]=Сервісы +Name[bg]=Услуги +Name[bn]=সার্ভিসসমূহ +Name[br]=Servijoù +Name[bs]=Servisi +Name[ca]=Serveis +Name[cs]=Služby +Name[csb]=Ùsłëżnotë +Name[cy]=Gwasanaethau +Name[da]=Tjenester +Name[de]=KDE-Dienste +Name[el]=Υπηρεσίες +Name[eo]=Servoj +Name[es]=Servicios +Name[et]=Teenused +Name[eu]=Zerbitzuak +Name[fa]=خدمات +Name[fi]=Palvelut +Name[fo]=Tænastur +Name[fy]=Tsjinsten +Name[ga]=Seirbhísí +Name[gl]=Servizos +Name[he]=שירותים +Name[hi]=सेवाएं +Name[hr]=Usluge +Name[hu]=Szolgáltatások +Name[is]=Þjónustur +Name[it]=Servizi +Name[ja]=サービス +Name[ka]=სერვისები +Name[kk]=Қызметтер +Name[km]=សេវា +Name[ko]=서비스 +Name[lo]=ບໍລິການ +Name[lt]=Tarnybos +Name[lv]=Servisi +Name[mk]=Сервиси +Name[mn]=КДЭ-Үйлчилгээ +Name[ms]=Servis +Name[mt]=Servizzi +Name[nb]=Tjenester +Name[nds]=KDE-Deensten +Name[ne]=सेवा +Name[nn]=Tenester +Name[nso]=Ditirelo +Name[pa]=ਸੇਵਾਵਾਂ +Name[pl]=Usługi +Name[pt]=Serviços +Name[pt_BR]=Serviços +Name[ro]=Servicii +Name[ru]=Сервисы +Name[rw]=Serivise +Name[se]=Bálvalusat +Name[sk]=Služby +Name[sl]=Storitve +Name[sr]=Сервиси +Name[sr@Latn]=Servisi +Name[sv]=Tjänster +Name[ta]=சேவைகள் +Name[te]=సేవలు +Name[tg]=Хидматҳо +Name[th]=บริการ +Name[tr]=Servisler +Name[tt]=Xezmätlär +Name[uk]=Служби +Name[uz]=Xizmatlar +Name[uz@cyrillic]=Хизматлар +Name[ven]=Dzitshumelo +Name[vi]=Các dịch vụ +Name[wa]=Siervices +Name[xh]=Iinkonzo +Name[zh_CN]=服务 +Name[zh_TW]=服務 +Name[zu]=Imisebenzi +Open=false diff --git a/konqueror/sidebar/trees/init/services/Makefile.am b/konqueror/sidebar/trees/init/services/Makefile.am new file mode 100644 index 000000000..8e8c2e2f8 --- /dev/null +++ b/konqueror/sidebar/trees/init/services/Makefile.am @@ -0,0 +1,2 @@ +konq_sidebartree_init_services_data_DATA = .directory audiocd.desktop printsystem.desktop media.desktop settings.desktop applications.desktop +konq_sidebartree_init_services_datadir = $(kde_datadir)/konqsidebartng/virtual_folders/services diff --git a/konqueror/sidebar/trees/init/services/applications.desktop b/konqueror/sidebar/trees/init/services/applications.desktop new file mode 100644 index 000000000..0996b0e9e --- /dev/null +++ b/konqueror/sidebar/trees/init/services/applications.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +Type=Link +URL=applications:/ +Icon=kmenu +Name=Applications +Name[af]=Programme +Name[ar]=التطبيقات +Name[az]=Proqram Tə'minatları +Name[be]=Праграмы +Name[bg]=Програми +Name[bn]=অ্যাপলিকেশন +Name[br]=Arloadoù +Name[bs]=Programi +Name[ca]=Aplicacions +Name[cs]=Aplikace +Name[csb]=Programë +Name[cy]=Cymhwysiadau +Name[da]=Programmer +Name[de]=Programme +Name[el]=Εφαρμογές +Name[eo]=Aplikaĵoj +Name[es]=Aplicaciones +Name[et]=Rakendused +Name[eu]=Aplikazioak +Name[fa]=کاربردها +Name[fi]=Sovellukset +Name[fy]=Programma's +Name[ga]=Feidhmchláir +Name[gl]=Aplicacións +Name[he]=יישומים +Name[hi]=अनुप्रयोग +Name[hr]=Aplikacije +Name[hu]=Alkalmazások +Name[is]=Forrit +Name[it]=Applicazioni +Name[ja]=アプリケーション +Name[ka]=პროგრამები +Name[kk]=Қолданбалар +Name[km]=កម្មវិធី +Name[ko]=응용 프로그램 +Name[lt]=Programos +Name[lv]=Aplikācijas +Name[mk]=Апликации +Name[ms]=Aplikasi +Name[mt]=Programmi KDE +Name[nb]=Programmer +Name[nds]=Programmen +Name[ne]=अनुप्रयोग +Name[nl]=Programma's +Name[nn]=Program +Name[pa]=ਕਾਰਜ +Name[pl]=Programy +Name[pt]=Aplicações +Name[pt_BR]=Aplicativos +Name[ro]=Aplicații +Name[ru]=Приложения +Name[rw]=Amaporogaramu +Name[se]=Prográmmat +Name[sk]=Aplikácie +Name[sl]=Programi +Name[sr]=Програми +Name[sr@Latn]=Programi +Name[sv]=Program +Name[ta]=பயன்பாடுகள் +Name[te]=కార్యక్రమాలు +Name[tg]=Барномаҳо +Name[th]=แอพพลิเคชัน KDE +Name[tr]=Uygulamalar +Name[tt]=Yazılımnar +Name[uk]=Програми +Name[uz]=Dasturlar +Name[uz@cyrillic]=Дастурлар +Name[vi]=Ứng dụng +Name[wa]=Programes +Name[zh_CN]=应用程序 +Name[zh_TW]=應用程式 +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/services/audiocd.desktop b/konqueror/sidebar/trees/init/services/audiocd.desktop new file mode 100644 index 000000000..a7a8e3f27 --- /dev/null +++ b/konqueror/sidebar/trees/init/services/audiocd.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Type=Link +URL=audiocd:/ +Icon=cdaudio_unmount +Name=Audio CD Browser +Name[af]=Musiek CD Blaaier +Name[ar]=متصفح الأقراص المدمجة الصوتية +Name[az]=Audio CD Səyyahı +Name[be]=Праглядальнік гукавых CD +Name[bg]=Аудио диск +Name[bn]=অডিও সিডি ব্রাউজার +Name[br]=Furcher ar CDoù klevet +Name[bs]=Audio CD preglednik +Name[ca]=Navegador d'àudio CD +Name[cs]=Prohlížeč zvukových CD +Name[csb]=Przezérnik audio CD +Name[cy]=Porydd CD Sain +Name[da]=Audio-cd-søger +Name[de]=Audio-CD-Browser +Name[el]=Περιηγητής CD ήχου +Name[eo]=Rigardilo por muzikaj lumdiskoj +Name[es]=Navegador de CD-Audio +Name[et]=Audio CD sirvija +Name[eu]=Audio CD arakatzailea +Name[fa]=مرورگر دیسک فشردۀ صوتی +Name[fi]=Audio CD:n selain +Name[fr]=Navigateur de CD audio +Name[fy]=Audio kompaktskiif blêder +Name[ga]=Brabhsálaí Dhlúthdhiosca Fuaime +Name[gl]=Navegador de CD de Audio +Name[he]=דפדפן תקליטורי שמע +Name[hi]=ऑडियो सीडी ब्राउज़र +Name[hr]=Glazbeni CD preglednik +Name[hu]=Hang-CD-böngésző +Name[is]=Tónlistardiskaflakkari +Name[it]=Navigazione dei CD audio +Name[ja]=オーディオ CD ブラウザ +Name[ka]=Audio CD-ს დათვალიერება +Name[kk]=Аудио CD шолғышы +Name[km]=កម្មវិធីរុករកស៊ីឌីសំឡេង +Name[lo]=ບາວເຊີ ຊີດີ ອໍດີໂອ້ +Name[lt]=Audio CD naršyklė +Name[lv]=Audio CD Pārlūks +Name[mk]=Прелистувач на аудио CD-а +Name[mn]=Аудио-КД-Хөтөч +Name[ms]=Pelayar CD Audio +Name[mt]=Browser CDs tal-Mużika +Name[nb]=Lyd-CD-leser +Name[nds]=Audio-CDs bekieken +Name[ne]=अडियो सीडी ब्राउजर +Name[nl]=Audio-cd Browser +Name[nn]=Lyd-CD-lesar +Name[nso]=Seinyakisi sa CD yeo e Kwagalago +Name[pa]=ਆਡੀਓ CD ਝਲਕਾਰਾ +Name[pl]=Przeglądarka audio CD +Name[pt]=Navegador de CDs Áudio +Name[pt_BR]=Navegador de CDs de Áudio +Name[ro]=Navigator CD audio +Name[ru]=Просмотр аудио CD +Name[rw]=Mucukumbuzi wa CD Inyumvo +Name[se]=Jietna-CD-logan +Name[sk]=Prehliadač zvukových CD +Name[sl]=Brskalnik po glasbenem CDju +Name[sr]=Прегледач аудио CD-ова +Name[sr@Latn]=Pregledač audio CD-ova +Name[sv]=Bläddrare för ljud-cd +Name[ta]=கேட்பொலி குறுந்தகடு உலாவி +Name[te]=ఆడియొ సిడి బ్రౌజర్ +Name[tg]=Тафсири Аудио CD +Name[th]=บราวเซอร์ซีดีเพลง +Name[tr]=Müzik CD +Name[tt]=Tawışlı CD Küzätüçe +Name[uk]=Навігатор аудіо КД +Name[uz]=Audio kompakt-disk brauzeri +Name[uz@cyrillic]=Аудио компакт-диск браузери +Name[ven]=Buronza ya CD ino thetsheleswa +Name[vi]=Duyệt CD nhạc +Name[wa]=Foyteuse des plakes lazer odio +Name[xh]=Umkhangeli zincwadi we CD Audio +Name[zh_CN]=音频 CD 浏览器 +Name[zh_TW]=音樂 CD 瀏覽器 +Name[zu]=Umcingi wama-CD ozwakalayo +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/services/media.desktop b/konqueror/sidebar/trees/init/services/media.desktop new file mode 100644 index 000000000..edff531f9 --- /dev/null +++ b/konqueror/sidebar/trees/init/services/media.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=Link +URL=media:/ +Icon=system +Name=Storage Media +Name[af]=Stoor Media +Name[ar]=وسائط التخزين +Name[be]=Носьбіты +Name[bg]=Съхраняващи устройства +Name[bn]=স্টোরেজ মিডিয়া +Name[bs]=Uređaji za smještaj podataka +Name[ca]=Suports d'emmagatzematge +Name[cs]=Úložná zařízení +Name[csb]=Zôpisowné media +Name[da]=Opbevaringsmedie +Name[de]=Speichermedien +Name[el]=Συσκευές αποθήκευσης +Name[eo]=Enmemoriga Medio +Name[es]=Dispositivos de almacenamiento +Name[et]=Andmekandjad +Name[eu]=Biltegiratze-euskarria +Name[fa]=رسانۀ ذخیرهگاه +Name[fi]=Tallennusmedia +Name[fr]=Support de stockage +Name[fy]=Opslachapparaten +Name[ga]=Meán Stórais +Name[gl]=Medios de armacenaxe +Name[he]=התקנים +Name[hi]=भंडार मीडिया +Name[hr]=Mediji za pohranjivanje +Name[hu]=Tárolóeszközök +Name[is]=Geymslumiðlar +Name[it]=Dispositivi di archiviazione +Name[ja]=記憶メディア +Name[ka]=მონაცემთა შენახვის მოწყობილობები +Name[kk]=Жинақтаушы құрылғылар +Name[km]=ឧបករណ៍ផ្ទុក +Name[lt]=Saugojimo įrenginiai +Name[lv]=Datu nesējs +Name[mk]=Медиуми за податоци +Name[ms]=Media Storan +Name[nb]=Lagringsenheter +Name[nds]=Spiekermedien +Name[ne]=भण्डारण मिडिया +Name[nl]=Opslagapparaten +Name[nn]=Lagringsmedium +Name[pa]=ਸਟੋਰੇਜ਼ ਮੀਡਿਆ +Name[pl]=Urządzenia przechowywania danych +Name[pt]=Dispositivos de Armazenamento +Name[pt_BR]=Mídia de Armazenamento +Name[ro]=Mediu de stocare +Name[ru]=Устройства хранения данных +Name[rw]=Uburyo bwo Kubika +Name[se]=Vurkenmedia +Name[sk]=Zálohovacie médiá +Name[sl]=Nosilci za shranjevanje +Name[sr]=Складишни медијуми +Name[sr@Latn]=Skladišni medijumi +Name[sv]=Lagringsmedia +Name[ta]=சேகரிப்பு ஊடகம் +Name[tg]=Захирагоҳи маълумот +Name[th]=สื่อเก็บข้อมูล +Name[tr]=Depolama Ortamı +Name[tt]=Saqlawlı Media +Name[uk]=Пристрої зберігання інформації +Name[uz]=Saqlash uskunalari +Name[uz@cyrillic]=Сақлаш ускуналари +Name[vi]=Ổ chứa Dữ liệu +Name[wa]=Sopoirts di wårdaedje +Name[zh_CN]=存储介质 +Name[zh_TW]=儲存媒體 +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/services/printsystem.desktop b/konqueror/sidebar/trees/init/services/printsystem.desktop new file mode 100644 index 000000000..b51737e50 --- /dev/null +++ b/konqueror/sidebar/trees/init/services/printsystem.desktop @@ -0,0 +1,85 @@ +[Desktop Entry] +Type=Link +URL=print:/ +Icon=fileprint +Name=Print System Browser +Name[af]=Drukker Stelsel Blaaier +Name[ar]=متصفح نظام الطباعة +Name[az]=Çap Sistemi Səyyahı +Name[be]=Праглядальнік сістэм друку +Name[bg]=Система за печат +Name[bn]=মুদ্রণ ব্যবস্থা ব্রাউজার +Name[bs]=Preglednik sistema štampe +Name[ca]=Navegador del sistema d'impressió +Name[cs]=Prohlížeč tiskového systému +Name[csb]=Przezérnik systemë drëkù +Name[cy]=Porydd y Cysawd Argraffu +Name[da]=Udskriftssystemsøger +Name[de]=Drucksystem-Browser +Name[el]=Προβολέας συστήματος εκτύπωσης +Name[eo]=Rigardilo por printosistemo +Name[es]=Navegador del sistema de impresión +Name[et]=Trükkimissüsteemi sirvija +Name[eu]=Inprimaketa sistemaren arakatzailea +Name[fa]=مرورگر سیستم چاپ +Name[fi]=Tulostusjärjestelmä +Name[fr]=Navigateur dans le système d'impression +Name[fy]=Printsysteemblêder +Name[ga]=Brabhsálaí an Chóras Priontála +Name[gl]=Navegador do Sistema de Impresión +Name[he]=דפדפן מערכות הדפסה +Name[hi]=मुद्ण तंत्र ब्राउज़र +Name[hr]=Preglednik sustava ispisivanja +Name[hu]=A nyomtatók böngészése +Name[is]=Prentaraflakk +Name[it]=Navigazione del sistema di stampa +Name[ja]=印刷システムブラウザ +Name[ka]=ბეჭდვის სისტემის დათვალიერება +Name[kk]=Басып шығару жүйесін шолғышы +Name[km]=កម្មវិធីរុករកប្រព័ន្ធបោះពុម្ព +Name[ko]=인쇄 시스템 탐색기 +Name[lo]=ການຮງກເບິ່ງລະບົບການພິມ +Name[lt]=Spausdinimo sistemos naršyklė +Name[lv]=Drukas Sistēmas Pārlūks +Name[mk]=Прелистувач на печатарскиот систем +Name[mn]=Хэдлэх системийн хөтөч +Name[ms]=Pelayar Sistem Cetak +Name[mt]=Browser tas-sistema ta' pprintjar +Name[nb]=Visning av utskriftssystem +Name[nds]=Drucksysteem bekieken +Name[ne]=मुद्रण प्रणाली ब्राउजर +Name[nl]=Afdruksysteembrowser +Name[nn]=Vising av utskriftssystem +Name[nso]=Seinyakisi sa System ya Kgatiso +Name[pa]=ਪਰਿੰਟ ਸਿਸਟਮ ਝਲਕਾਰਾ +Name[pl]=Przeglądarka systemu drukowania +Name[pt]=Navegador do Sistema de Impressão +Name[pt_BR]=Sistema de Impressão +Name[ro]=Navigator sistem tipărire +Name[ru]=Просмотр системы печати +Name[rw]=Mucukumbuzi Sisitemu Gucapa +Name[se]=Čájet čálihanvuogádaga +Name[sk]=Prehliadač tlačového systému +Name[sl]=Brskalnik po tiskalniškem sistemu +Name[sr]=Прегледач система за штампу +Name[sr@Latn]=Pregledač sistema za štampu +Name[sv]=Bläddrare för utskriftssystem +Name[ta]=அச்சு அமைப்பு உலாவி +Name[te]=ప్రచురణ వ్యవస్థ బ్రౌజర్ +Name[tg]=Чопи тафсири система +Name[th]=เรียกดูระบบการพิมพ์ +Name[tr]=Yazdırma Sistemi Tarayıcı +Name[tt]=Bastıru Sistemen Küzätüçe +Name[uk]=Навігація системи друку +Name[uz]=Bosib chiqarish tizim brauzeri +Name[uz@cyrillic]=Босиб чиқариш тизим браузери +Name[ven]=Buronza ya maitele au phirintha +Name[vi]=Duyệt Hệ thống In ấn +Name[wa]=Foyteuse do sistinme d' imprimaedje +Name[xh]=Shicilela Umkhangeli zincwadi Wendlela +Name[zh_CN]=打印系统浏览器 +Name[zh_TW]=列印系統瀏覽器 +Name[zu]=Umcingi wesistimu yokushicilela +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/services/settings.desktop b/konqueror/sidebar/trees/init/services/settings.desktop new file mode 100644 index 000000000..416d5a69b --- /dev/null +++ b/konqueror/sidebar/trees/init/services/settings.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=Link +URL=settings:/ +Icon=kcontrol +Name=Settings +Name[af]=Instellings +Name[ar]=التعيينات +Name[az]=Qurğular +Name[be]=Настаўленні +Name[bg]=Настройки +Name[bn]=সেটিংস +Name[br]=Dibarzhoù +Name[bs]=Postavke +Name[ca]=Preferències +Name[cs]=Nastavení +Name[csb]=Ùstôw +Name[cy]=Gosodiadau +Name[da]=Opsætning +Name[de]=Einstellungen +Name[el]=Ρυθμίσεις +Name[eo]=Agordo +Name[es]=Preferencias +Name[et]=Seadistused +Name[eu]=Ezarpenak +Name[fa]=تنظیمات +Name[fi]=Asetukset +Name[fr]=Configuration +Name[fy]=Ynstellings +Name[ga]=Socruithe +Name[gl]=Opcións +Name[he]=הגדרות +Name[hi]=विन्यास +Name[hr]=Postavke +Name[hsb]=Nastajenja +Name[hu]=Beállítások +Name[is]=Stillingar +Name[it]=Impostazioni +Name[ja]=設定 +Name[ka]=პარამეტრები +Name[kk]=Параметрлері +Name[km]=ការកំណត់ +Name[ko]=설정 +Name[lt]=Parinktys +Name[lv]=Parametri +Name[mk]=Поставувања +Name[mn]=Тохируулга +Name[ms]=Tempatan +Name[nb]=Innstillinger +Name[nds]=Instellen +Name[ne]=सेटिङ +Name[nl]=Instellingen +Name[nn]=Innstillingar +Name[pa]=ਸੈਟਿੰਗ +Name[pl]=Ustawienia +Name[pt]=Configuração +Name[pt_BR]=Configurações +Name[ro]=Setări +Name[ru]=Настройка +Name[rw]=Amagenamiterere +Name[se]=Heivehusat +Name[sk]=Nastavenia +Name[sl]=Nastavitve +Name[sr]=Поставке +Name[sr@Latn]=Postavke +Name[sv]=Inställningar +Name[ta]=அமைப்புகள் +Name[te]=అమరికలు +Name[tg]=Танзимот +Name[th]=ตั้งค่าต่างๆ +Name[tr]=Ayarlar +Name[tt]=Caylaw +Name[uk]=Параметри +Name[uz]=Moslamalar +Name[uz@cyrillic]=Мосламалар +Name[vi]=Thiết lập +Name[wa]=Apontiaedjes +Name[zh_CN]=设置 +Name[zh_TW]=設定 +Open=false +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/system.desktop b/konqueror/sidebar/trees/init/system.desktop new file mode 100644 index 000000000..490b4ef7f --- /dev/null +++ b/konqueror/sidebar/trees/init/system.desktop @@ -0,0 +1,139 @@ +[Desktop Entry] +Type=Link +URL=system:/ +Icon=system +Name=System +Name[af]=Stelsel +Name[ar]=النظام +Name[az]=Sistem +Name[be]=Сістэма +Name[bg]=Система +Name[bn]=সিস্টেম +Name[br]=Reizhiad +Name[bs]=Sistem +Name[ca]=Sistema +Name[cs]=Systém +Name[csb]=Systema +Name[cy]=Cysawd +Name[el]=Σύστημα +Name[eo]=Sistemo +Name[es]=Sistema +Name[et]=Süsteem +Name[eu]=Sistema +Name[fa]=سیستم +Name[fi]=Järjestelmä +Name[fo]=Kervi +Name[fr]=Système +Name[fy]=Systeem +Name[ga]=Córas +Name[gl]=Sistema +Name[he]=מערכת +Name[hi]=तंत्र +Name[hr]=Sustav +Name[hu]=Rendszer +Name[id]=Sistem +Name[is]=Kerfi +Name[it]=Sistema +Name[ja]=システム +Name[ka]=სისტემა +Name[kk]=Жүйелік +Name[km]=ប្រព័ន្ធ +Name[ko]=시스템 +Name[lo]=ຈັດການລະບົບ +Name[lt]=Sistema +Name[lv]=Sistēma +Name[mk]=Систем +Name[mn]=Систем +Name[ms]=Sistem +Name[mt]=Sistema +Name[nds]=Systeem +Name[ne]=प्रणाली +Name[nl]=Systeem +Name[oc]=Sistemo +Name[pa]=ਸਿਸਟਮ +Name[pt]=Sistema +Name[pt_BR]=Sistema +Name[ro]=Sistem +Name[ru]=Система +Name[rw]=Sisitemu +Name[se]=Vuogádat +Name[sk]=Systém +Name[sl]=Sistem +Name[sr]=Систем +Name[sr@Latn]=Sistem +Name[ss]=Umshini +Name[ta]=அமைப்பு +Name[te]=వ్యవస్థ +Name[tg]=Система +Name[th]=ระบบ +Name[tr]=Sistem +Name[tt]=Sistem +Name[uk]=Система +Name[uz]=Tizim +Name[uz@cyrillic]=Тизим +Name[ven]=Maitele +Name[vi]=Hệ thống +Name[wa]=Sistinme +Name[xh]=Indlela esestyenziswayo +Name[zh_CN]=系统 +Name[zh_TW]=系統 +Name[zu]=Isistimu +Comment=This folder allows you to access common places on your computer +Comment[af]=Hierdie gids laat jou toe om algemene plekke op jou rekenaar te besoek +Comment[ar]=هذا المجلّد يسمح لك بالوصول إلى مواقع مشتركة على حاسوبك +Comment[be]=Гэтая тэчка дазваляе атрымаць хуткі доступ да розных важных месцаў на вашым кампутары +Comment[bg]=Директория за достъп до често използваните места в компютъра +Comment[bn]=এই ফোল্ডারটি আপনার কম্পিউটারে সাধারণত ব্যবহৃত অবস্থানগুলিতে চটপট চলে যেতে সাহায্য করে +Comment[bs]=Ovaj direktorij vam omogućuje pristup uobičajenim mjestima na vašem računaru +Comment[ca]=Aquesta carpeta us permet accedir a llocs usuals de l'ordinador +Comment[cs]=Tato složka zpřístupňuje často používaná umístění na vašem počítači +Comment[csb]=Nen katalog dôwô mòżnotã przistãpù do nôczãsczi brëkòwónëch placów w twòjim kòmpùtrze +Comment[da]=Denne mappe giver adgang til almindelige steder på din computer +Comment[de]=Dieser Ordner ermöglicht den Zugriff auf gebräuchliche Systembereiche des Computers +Comment[el]=Αυτός ο φάκελος σας επιτρέπει την πρόσβαση σε τυπικές τοποθεσίες του συστήματός σας +Comment[eo]=Tiu ĉi dosierujo atingebligas al viaj ofte vizititaj lokoj en via komputilo +Comment[es]=Esta carpeta permite acceder a lugares usuales en su equipo +Comment[et]=See kataloog võimaldab juurdepääsu tavalistele kohtadele su arvutis +Comment[eu]=Karpeta honek zure ordenagailuaren leku arruntetarako sarbidea ematen dizu +Comment[fa]=این پوشه اجازۀ دستیابی به جاهای مشترک در رایانۀ شما را میدهد +Comment[fi]=Tämä kansio sallii pääsyn tietokoneesi yleisiin kohteisiin +Comment[fr]=Ce dossier vous permet d'accéder aux endroits de votre ordinateur régulièrement utilisés +Comment[fy]=Dizze map jout tagong ta algemiene plakken yn jo kompjûter +Comment[ga]=Ceadaíonn an fillteán seo duit áiteanna coitianta a rochtain ar do ríomhaire +Comment[gl]=Este cartafol permite-lle aceder a lugares habituais do seu ordenador +Comment[he]=תיקייה זו מאפשרת לך לגשת את המקומות המועדפים עליך במערכת שלך +Comment[hr]=Ova mapa omogućuje pristup uobičajenim lokacijama na računalu +Comment[hu]=Néhány fontosabb rendszerkönyvtár elérését teszi lehetővé +Comment[is]=Þessi mappa veitir aðgang að algengum stöðum á tölvunni þinni +Comment[it]=Questa cartella permette di accedere agli oggetti comuni del tuo computer +Comment[ja]=このフォルダからコンピュータ上のよく使われる場所にアクセスできます +Comment[kk]=Бұл қапшық компьютердегі ортақ орындарға қатынауға мүмкіндік береді +Comment[km]=ថតនេះអនុញ្ញាតឲ្យអ្នកចូលដំណើរការកន្លែងទូទៅលើកុំព្យូទ័ររបស់អ្នក +Comment[lt]=Šio aplanko padedami pasieksite dažniausiai lankomas kompiuterio vietas +Comment[mk]=Оваа папка ви овозможува пристап до вообичаените места на вашиот компјутер +Comment[nb]=Denne mappa gir deg tilgang til vanlige steder på din datamaskin +Comment[nds]=Mit dissen Orner kannst Du op en Reeg faken bruukte Öörd togriepen +Comment[ne]=यो फोल्डरले तपाईँलाई कम्प्युटरको साझा स्थानहरूमा पहुँच अनुमति दिन्छ +Comment[nl]=Deze map geeft toegang tot algemene plekken van uw desktop +Comment[nn]=Denne mappa gir deg tilgang til nokre vanlege stader på datamaskina +Comment[pa]=ਇਹ ਫੋਲਡਰ ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਕੰਪਿਊਟਰ 'ਚ ਆਮ ਥਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਸਹਾਇਕ ਹੈ +Comment[pl]=Ten folder umożliwia dostęp do najczęściej używanych miejsc w Twoim komputerze +Comment[pt]=Esta pasta permite aceder a alguns locais comuns no seu computador +Comment[pt_BR]=Esta pasta permite que você acesse lugares comuns em seu computador +Comment[ro]=Acest folder vă permite să accesați locurile uzuale pe computerul dvs. +Comment[ru]=Часто используемые папки +Comment[sk]=Tento priečinok umožňuje pristupovať na spoločné miesta na tomto počítači +Comment[sl]=Ta mapa omogoča dostop do pomembnih lokacij na vašem računalniku +Comment[sr]=Ова фасцикла омогућава приступ уобичајеним местима на вашем рачунару +Comment[sr@Latn]=Ova fascikla omogućava pristup uobičajenim mestima na vašem računaru +Comment[sv]=Den här katalogen gör det möjligt att komma åt vanliga platser på din dator +Comment[th]=โฟลเดอร์นี้อนุญาตให้คุณเข้าถึงสถานที่ทั่วๆ ไปในเครื่องคอมพิวเตอร์ของคุณ +Comment[tr]=Bu klasör bilgisayarınızdaki belirli yerlere erişmenizi sağlar +Comment[uk]=Ця тека надає доступ до спільних місць у вашому комп'ютері +Comment[vi]=Thư mục này cho phép bạn truy cập vào các nơi thông dụng của máy tính +Comment[wa]=Ci ridant chal vos permete d' aler ås comonès plaeces so vosse copiutrece +Comment[zh_CN]=此文件夹允许您访问计算机中的公共位置 +Comment[zh_TW]=這個資料夾允許存取您電腦上的共同空間 +Open=true +X-KDE-TreeModule=Directory +X-KDE-KonqSidebarModule=konqsidebar_tree diff --git a/konqueror/sidebar/trees/init/virtualfolderadd.desktop b/konqueror/sidebar/trees/init/virtualfolderadd.desktop new file mode 100644 index 000000000..0af894ac6 --- /dev/null +++ b/konqueror/sidebar/trees/init/virtualfolderadd.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=Link +URL= +Icon=folder +Name=Folder +Name[af]=Gids +Name[ar]=المجلد +Name[az]=Qovluq +Name[be]=Тэчка +Name[bg]=Директория +Name[bn]=ফোল্ডার +Name[br]=Renkell +Name[bs]=Direktorij +Name[ca]=Carpeta +Name[cs]=Složka +Name[csb]=Katalog +Name[cy]=Plygell +Name[da]=Mappe +Name[de]=Ordner +Name[el]=Φάκελος +Name[eo]=Dosierujo +Name[es]=Carpeta +Name[et]=Kataloog +Name[eu]=Karpeta +Name[fa]=پوشه +Name[fi]=Kansio +Name[fr]=Dossier +Name[fy]=Map +Name[ga]=Fillteán +Name[gl]=Cartafol +Name[he]=תיקייה +Name[hi]=फ़ोल्डर +Name[hr]=Mapa +Name[hu]=Könyvtár +Name[is]=Mappa +Name[it]=Cartella +Name[ja]=フォルダ +Name[ka]=საქაღალდე +Name[kk]=Қапшық +Name[km]=ថត +Name[ko]=홈 폴더 +Name[lt]=Aplankas +Name[lv]=Mape +Name[mk]=Папка +Name[mn]=хавтас +Name[mt]=Direttorju +Name[nb]=Mappe +Name[nds]=Orner +Name[ne]=फोल्डर +Name[nl]=Map +Name[nn]=Mappe +Name[pa]=ਫੋਲਡਰ +Name[pl]=Katalog +Name[pt]=Pasta +Name[pt_BR]=Pasta +Name[ru]=Папка +Name[rw]=Ububiko +Name[se]=Máhppa +Name[sk]=Priečinok +Name[sl]=Mapa +Name[sr]=Фасцикла +Name[sr@Latn]=Fascikla +Name[sv]=Katalog +Name[ta]=அடைவு +Name[te]=ఫొల్డర్ +Name[tg]=Феҳрист +Name[th]=โฟลเดอร์ +Name[tr]=Dizin +Name[tt]=Törgäk +Name[uk]=Тека +Name[uz]=Jild +Name[uz@cyrillic]=Жилд +Name[vi]=Thư mục +Name[wa]=Ridant +Name[zh_CN]=文件夹 +Name[zh_TW]=資料夾 + +Open=false +X-KDE-KonqSidebarAddParam= +X-KDE-KonqSidebarAddModule=konqsidebar_tree +X-KDE-KonqSidebarUniversal=true diff --git a/konqueror/sidebar/trees/konq_sidebartree.cpp b/konqueror/sidebar/trees/konq_sidebartree.cpp new file mode 100644 index 000000000..e30e21ac9 --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartree.cpp @@ -0,0 +1,1048 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + 2000 Carsten Pfeiffer <[email protected]> + 2003 Waldo Bastian <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_sidebartreemodule.h" + +#include <qclipboard.h> +#include <qcursor.h> +#include <qdir.h> +#include <qheader.h> +#include <qpopupmenu.h> +#include <qtimer.h> + +#include <dcopclient.h> +#include <dcopref.h> + +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kdesktopfile.h> +#include <kdirnotify_stub.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <kinputdialog.h> +#include <kio/netaccess.h> +#include <kmimetype.h> +#include <kprocess.h> +#include <kpropertiesdialog.h> +#include <kprotocolinfo.h> +#include <kstandarddirs.h> +#include <kurldrag.h> + +#include <stdlib.h> +#include <assert.h> + + +static const int autoOpenTimeout = 750; + + +getModule KonqSidebarTree::getPluginFactory(QString name) +{ + if (!pluginFactories.contains(name)) + { + KLibLoader *loader = KLibLoader::self(); + QString libName = pluginInfo[name]; + KLibrary *lib = loader->library(QFile::encodeName(libName)); + if (lib) + { + // get the create_ function + QString factory = "create_" + libName; + void *create = lib->symbol(QFile::encodeName(factory)); + if (create) + { + getModule func = (getModule)create; + pluginFactories.insert(name, func); + kdDebug()<<"Added a module"<<endl; + } + else + { + kdWarning()<<"No create function found in"<<libName<<endl; + } + } + else + kdWarning() << "Module " << libName << " can't be loaded!" << endl; + } + + return pluginFactories[name]; +} + +void KonqSidebarTree::loadModuleFactories() +{ + pluginFactories.clear(); + pluginInfo.clear(); + KStandardDirs *dirs=KGlobal::dirs(); + QStringList list=dirs->findAllResources("data","konqsidebartng/dirtree/*.desktop",false,true); + + + for (QStringList::ConstIterator it=list.begin();it!=list.end();++it) + { + KSimpleConfig ksc(*it); + ksc.setGroup("Desktop Entry"); + QString name = ksc.readEntry("X-KDE-TreeModule"); + QString libName = ksc.readEntry("X-KDE-TreeModule-Lib"); + if ((name.isEmpty()) || (libName.isEmpty())) + {kdWarning()<<"Bad Configuration file for a dirtree module "<<*it<<endl; continue;} + + //Register the library info. + pluginInfo[name] = libName; + } +} + + +class KonqSidebarTree_Internal +{ +public: + DropAcceptType m_dropMode; + QStringList m_dropFormats; +}; + + +KonqSidebarTree::KonqSidebarTree( KonqSidebar_Tree *parent, QWidget *parentWidget, int virt, const QString& path ) + : KListView( parentWidget ), + m_currentTopLevelItem( 0 ), + m_toolTip( this ), + m_scrollingLocked( false ), + m_collection( 0 ) +{ + d = new KonqSidebarTree_Internal; + d->m_dropMode = SidebarTreeMode; + + loadModuleFactories(); + + setAcceptDrops( true ); + viewport()->setAcceptDrops( true ); + m_lstModules.setAutoDelete( true ); + + setSelectionMode( QListView::Single ); + setDragEnabled(true); + + m_part = parent; + + m_animationTimer = new QTimer( this ); + connect( m_animationTimer, SIGNAL( timeout() ), + this, SLOT( slotAnimation() ) ); + + m_currentBeforeDropItem = 0; + m_dropItem = 0; + m_bOpeningFirstChild=false; + + addColumn( QString::null ); + header()->hide(); + setTreeStepSize(15); + + m_autoOpenTimer = new QTimer( this ); + connect( m_autoOpenTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoOpenFolder() ) ); + + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( slotDoubleClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( mouseButtonPressed(int, QListViewItem*, const QPoint&, int)), + this, SLOT( slotMouseButtonPressed(int, QListViewItem*, const QPoint&, int)) ); + connect( this, SIGNAL( mouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ), + this, SLOT( slotMouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ) ); + connect( this, SIGNAL( returnPressed( QListViewItem * ) ), + this, SLOT( slotDoubleClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( selectionChanged() ), + this, SLOT( slotSelectionChanged() ) ); + + connect( this, SIGNAL(itemRenamed(QListViewItem*, const QString &, int)), + this, SLOT(slotItemRenamed(QListViewItem*, const QString &, int))); + +/* assert( m_part->getInterfaces()->getInstance()->dirs ); + QString dirtreeDir = m_part->getInterfaces()->getInstance()->dirs()->saveLocation( "data", "konqueror/dirtree/" ); */ + +// assert( KGlobal::dirs() ); +// QString dirtreeDir = part->getInterfaces()->getInstance()->dirs()->saveLocation( "data", "konqueror/dirtree/" ); + + if (virt==VIRT_Folder) + { + m_dirtreeDir.dir.setPath(KGlobal::dirs()->saveLocation("data","konqsidebartng/virtual_folders/"+path+"/")); + m_dirtreeDir.relDir=path; + } + else + m_dirtreeDir.dir.setPath( path ); + kdDebug(1201)<<m_dirtreeDir.dir.path()<<endl; + m_dirtreeDir.type=virt; + // Initial parsing + rescanConfiguration(); + + if (firstChild()) + { + m_bOpeningFirstChild = true; + firstChild()->setOpen(true); + m_bOpeningFirstChild = false; + } + + setFrameStyle( QFrame::ToolBarPanel | QFrame::Raised ); +} + +KonqSidebarTree::~KonqSidebarTree() +{ + clearTree(); + + delete d; +} + +void KonqSidebarTree::itemDestructed( KonqSidebarTreeItem *item ) +{ + stopAnimation(item); + + if (item == m_currentBeforeDropItem) + { + m_currentBeforeDropItem = 0; + } +} + +void KonqSidebarTree::setDropFormats(const QStringList &formats) +{ + d->m_dropFormats = formats; +} + +void KonqSidebarTree::clearTree() +{ + m_lstModules.clear(); + m_topLevelItems.clear(); + m_mapCurrentOpeningFolders.clear(); + m_currentBeforeDropItem = 0; + clear(); + + if (m_dirtreeDir.type==VIRT_Folder) + { + setRootIsDecorated( true ); + } + else + { + setRootIsDecorated( false ); + } +} + +void KonqSidebarTree::followURL( const KURL &url ) +{ + // Maybe we're there already ? + KonqSidebarTreeItem *selection = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + if (selection && selection->externalURL().equals( url, true )) + { + ensureItemVisible( selection ); + return; + } + + kdDebug(1201) << "KonqDirTree::followURL: " << url.url() << endl; + QPtrListIterator<KonqSidebarTreeTopLevelItem> topItem ( m_topLevelItems ); + for (; topItem.current(); ++topItem ) + { + if ( topItem.current()->externalURL().isParentOf( url ) ) + { + topItem.current()->module()->followURL( url ); + return; // done + } + } + kdDebug(1201) << "KonqDirTree::followURL: Not found" << endl; +} + +void KonqSidebarTree::contentsDragEnterEvent( QDragEnterEvent *ev ) +{ + m_dropItem = 0; + m_currentBeforeDropItem = selectedItem(); + // Save the available formats + m_lstDropFormats.clear(); + for( int i = 0; ev->format( i ); i++ ) + if ( *( ev->format( i ) ) ) + m_lstDropFormats.append( ev->format( i ) ); +} + +void KonqSidebarTree::contentsDragMoveEvent( QDragMoveEvent *e ) +{ + QListViewItem *item = itemAt( contentsToViewport( e->pos() ) ); + + // Accept drops on the background, if URLs + if ( !item && m_lstDropFormats.contains("text/uri-list") ) + { + m_dropItem = 0; + e->acceptAction(); + if (selectedItem()) + setSelected( selectedItem(), false ); // no item selected + return; + } + + if (item && static_cast<KonqSidebarTreeItem*>(item)->acceptsDrops( m_lstDropFormats )) { + d->m_dropMode = SidebarTreeMode; + + if ( !item->isSelectable() ) + { + m_dropItem = 0; + m_autoOpenTimer->stop(); + e->ignore(); + return; + } + + e->acceptAction(); + + setSelected( item, true ); + + if ( item != m_dropItem ) + { + m_autoOpenTimer->stop(); + m_dropItem = item; + m_autoOpenTimer->start( autoOpenTimeout ); + } + } else { + d->m_dropMode = KListViewMode; + KListView::contentsDragMoveEvent(e); + } +} + +void KonqSidebarTree::contentsDragLeaveEvent( QDragLeaveEvent *ev ) +{ + // Restore the current item to what it was before the dragging (#17070) + if ( m_currentBeforeDropItem ) + setSelected( m_currentBeforeDropItem, true ); + else + setSelected( m_dropItem, false ); // no item selected + m_currentBeforeDropItem = 0; + m_dropItem = 0; + m_lstDropFormats.clear(); + + if (d->m_dropMode == KListViewMode) { + KListView::contentsDragLeaveEvent(ev); + } +} + +void KonqSidebarTree::contentsDropEvent( QDropEvent *ev ) +{ + if (d->m_dropMode == SidebarTreeMode) { + m_autoOpenTimer->stop(); + + if ( !selectedItem() ) + { + // KonqOperations::doDrop( 0L, m_dirtreeDir.dir, ev, this ); + KURL::List urls; + if ( KURLDrag::decode( ev, urls ) ) + { + for(KURL::List::ConstIterator it = urls.begin(); + it != urls.end(); ++it) + { + addURL(0, *it); + } + } + } + else + { + KonqSidebarTreeItem *selection = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + selection->drop( ev ); + } + } else { + KListView::contentsDropEvent(ev); + } +} + +static QString findUniqueFilename(const QString &path, QString filename) +{ + if (filename.endsWith(".desktop")) + filename.truncate(filename.length()-8); + + QString name = filename; + int n = 2; + while(QFile::exists(path + filename + ".desktop")) + { + filename = QString("%2_%1").arg(n++).arg(name); + } + return path+filename+".desktop"; +} + +void KonqSidebarTree::addURL(KonqSidebarTreeTopLevelItem* item, const KURL & url) +{ + QString path; + if (item) + path = item->path(); + else + path = m_dirtreeDir.dir.path(); + + KURL destUrl; + + if (url.isLocalFile() && url.fileName().endsWith(".desktop")) + { + QString filename = findUniqueFilename(path, url.fileName()); + destUrl.setPath(filename); + KIO::NetAccess::copy(url, destUrl, this); + } + else + { + QString name = url.host(); + if (name.isEmpty()) + name = url.fileName(); + QString filename = findUniqueFilename(path, name); + destUrl.setPath(filename); + + KDesktopFile cfg(filename); + cfg.writeEntry("Encoding", "UTF-8"); + cfg.writeEntry("Type","Link"); + cfg.writeEntry("URL", url.url()); + QString icon = "folder"; + if (!url.isLocalFile()) + icon = KMimeType::favIconForURL(url); + if (icon.isEmpty()) + icon = KProtocolInfo::icon( url.protocol() ); + cfg.writeEntry("Icon", icon); + cfg.writeEntry("Name", name); + cfg.writeEntry("Open", false); + cfg.sync(); + } + + KDirNotify_stub allDirNotify( "*", "KDirNotify*" ); + destUrl.setPath( destUrl.directory() ); + allDirNotify.FilesAdded( destUrl ); + + if (item) + item->setOpen(true); +} + +bool KonqSidebarTree::acceptDrag(QDropEvent* e) const +{ + // for KListViewMode... + for( int i = 0; e->format( i ); i++ ) + if ( d->m_dropFormats.contains(e->format( i ) ) ) + return true; + return false; +} + +QDragObject* KonqSidebarTree::dragObject() +{ + KonqSidebarTreeItem* item = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + if ( !item ) + return 0; + + QDragObject* drag = item->dragObject( viewport(), false ); + if ( !drag ) + return 0; + + const QPixmap *pix = item->pixmap(0); + if ( pix && drag->pixmap().isNull() ) + drag->setPixmap( *pix ); + + return drag; +} + +void KonqSidebarTree::leaveEvent( QEvent *e ) +{ + KListView::leaveEvent( e ); +// emitStatusBarText( QString::null ); +} + + +void KonqSidebarTree::slotDoubleClicked( QListViewItem *item ) +{ + //kdDebug(1201) << "KonqSidebarTree::slotDoubleClicked " << item << endl; + if ( !item ) + return; + + if ( !static_cast<KonqSidebarTreeItem*>(item)->isClickable() ) + return; + + slotExecuted( item ); + item->setOpen( !item->isOpen() ); +} + +void KonqSidebarTree::slotExecuted( QListViewItem *item ) +{ + kdDebug(1201) << "KonqSidebarTree::slotExecuted " << item << endl; + if ( !item ) + return; + + if ( !static_cast<KonqSidebarTreeItem*>(item)->isClickable() ) + return; + + KonqSidebarTreeItem *dItem = static_cast<KonqSidebarTreeItem *>( item ); + + KParts::URLArgs args; + + args.serviceType = dItem->externalMimeType(); + args.trustedSource = true; + KURL externalURL = dItem->externalURL(); + if ( !externalURL.isEmpty() ) + openURLRequest( externalURL, args ); +} + +void KonqSidebarTree::slotMouseButtonPressed( int _button, QListViewItem* _item, const QPoint&, int col ) +{ + KonqSidebarTreeItem * item = static_cast<KonqSidebarTreeItem*>( _item ); + if (_button == RightButton) + { + if ( item && col < 2) + { + item->setSelected( true ); + item->rightButtonPressed(); + } + } +} + +void KonqSidebarTree::slotMouseButtonClicked(int _button, QListViewItem* _item, const QPoint&, int col) +{ + KonqSidebarTreeItem * item = static_cast<KonqSidebarTreeItem*>(_item); + if(_item && col < 2) + { + switch( _button ) { + case LeftButton: + slotExecuted( item ); + break; + case MidButton: + item->middleButtonClicked(); + break; + } + } +} + +void KonqSidebarTree::slotAutoOpenFolder() +{ + m_autoOpenTimer->stop(); + + if ( !m_dropItem || m_dropItem->isOpen() ) + return; + + m_dropItem->setOpen( true ); + m_dropItem->repaint(); +} + +void KonqSidebarTree::rescanConfiguration() +{ + kdDebug(1201) << "KonqSidebarTree::rescanConfiguration()" << endl; + m_autoOpenTimer->stop(); + clearTree(); + if (m_dirtreeDir.type==VIRT_Folder) + { + kdDebug(1201)<<"KonqSidebarTree::rescanConfiguration()-->scanDir"<<endl; + scanDir( 0, m_dirtreeDir.dir.path(), true); + + } + else + { + kdDebug(1201)<<"KonqSidebarTree::rescanConfiguration()-->loadTopLevel"<<endl; + loadTopLevelItem( 0, m_dirtreeDir.dir.path() ); + } +} + +void KonqSidebarTree::slotSelectionChanged() +{ + if ( !m_dropItem ) // don't do this while the dragmove thing + { + KonqSidebarTreeItem * item = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + if ( item ) + item->itemSelected(); + /* else -- doesn't seem to happen + {} */ + } +} + +void KonqSidebarTree::FilesAdded( const KURL & dir ) +{ + kdDebug(1201) << "KonqSidebarTree::FilesAdded " << dir.url() << endl; + if ( m_dirtreeDir.dir.isParentOf( dir ) ) + // We use a timer in case of DCOP re-entrance.. + QTimer::singleShot( 0, this, SLOT( rescanConfiguration() ) ); +} + +void KonqSidebarTree::FilesRemoved( const KURL::List & urls ) +{ + //kdDebug(1201) << "KonqSidebarTree::FilesRemoved " << urls.count() << endl; + for ( KURL::List::ConstIterator it = urls.begin() ; it != urls.end() ; ++it ) + { + //kdDebug(1201) << "KonqSidebarTree::FilesRemoved " << (*it).prettyURL() << endl; + if ( m_dirtreeDir.dir.isParentOf( *it ) ) + { + QTimer::singleShot( 0, this, SLOT( rescanConfiguration() ) ); + kdDebug(1201) << "KonqSidebarTree::FilesRemoved done" << endl; + return; + } + } +} + +void KonqSidebarTree::FilesChanged( const KURL::List & urls ) +{ + //kdDebug(1201) << "KonqSidebarTree::FilesChanged" << endl; + // not same signal, but same implementation + FilesRemoved( urls ); +} + +void KonqSidebarTree::scanDir( KonqSidebarTreeItem *parent, const QString &path, bool isRoot ) +{ + QDir dir( path ); + + if ( !dir.isReadable() ) + return; + + kdDebug(1201) << "scanDir " << path << endl; + + QStringList entries = dir.entryList( QDir::Files ); + QStringList dirEntries = dir.entryList( QDir::Dirs | QDir::NoSymLinks ); + dirEntries.remove( "." ); + dirEntries.remove( ".." ); + + if ( isRoot ) + { + bool copyConfig = ( entries.count() == 0 && dirEntries.count() == 0 ); + if (!copyConfig) + { + // Check version number + // Version 1 was the dirtree of KDE 2.0.x (no versioning at that time, so default) + // Version 2 includes the history + // Version 3 includes the bookmarks + // Version 4 includes lan.desktop and floppy.desktop, Alex + // Version 5 includes the audiocd browser + // Version 6 includes the printmanager and lan browser + const int currentVersion = 6; + QString key = QString::fromLatin1("X-KDE-DirTreeVersionNumber"); + KSimpleConfig versionCfg( path + "/.directory" ); + int versionNumber = versionCfg.readNumEntry( key, 1 ); + kdDebug(1201) << "KonqSidebarTree::scanDir found version " << versionNumber << endl; + if ( versionNumber < currentVersion ) + { + versionCfg.writeEntry( key, currentVersion ); + versionCfg.sync(); + copyConfig = true; + } + } + if (copyConfig) + { + // We will copy over the configuration for the dirtree, from the global directory + QStringList dirtree_dirs = KGlobal::dirs()->findDirs("data","konqsidebartng/virtual_folders/"+m_dirtreeDir.relDir+"/"); + + +// QString dirtree_dir = KGlobal::dirs()->findDirs("data","konqsidebartng/virtual_folders/"+m_dirtreeDir.relDir+"/").last(); // most global +// kdDebug(1201) << "KonqSidebarTree::scanDir dirtree_dir=" << dirtree_dir << endl; + + /* + // debug code + + QStringList blah = m_part->getInterfaces->getInstance()->dirs()->dirs()->findDirs( "data", "konqueror/dirtree" ); + QStringList::ConstIterator eIt = blah.begin(); + QStringList::ConstIterator eEnd = blah.end(); + for (; eIt != eEnd; ++eIt ) + kdDebug(1201) << "KonqSidebarTree::scanDir findDirs got me " << *eIt << endl; + // end debug code + */ + + for (QStringList::const_iterator ddit=dirtree_dirs.begin();ddit!=dirtree_dirs.end();++ddit) { + QString dirtree_dir=*ddit; + if (dirtree_dir==path) continue; + // if ( !dirtree_dir.isEmpty() && dirtree_dir != path ) + { + QDir globalDir( dirtree_dir ); + Q_ASSERT( globalDir.isReadable() ); + // Only copy the entries that don't exist yet in the local dir + QStringList globalDirEntries = globalDir.entryList(); + QStringList::ConstIterator eIt = globalDirEntries.begin(); + QStringList::ConstIterator eEnd = globalDirEntries.end(); + for (; eIt != eEnd; ++eIt ) + { + //kdDebug(1201) << "KonqSidebarTree::scanDir dirtree_dir contains " << *eIt << endl; + if ( *eIt != "." && *eIt != ".." + && !entries.contains( *eIt ) && !dirEntries.contains( *eIt ) ) + { // we don't have that one yet -> copy it. + QString cp("cp -R -- "); + cp += KProcess::quote(dirtree_dir + *eIt); + cp += " "; + cp += KProcess::quote(path); + kdDebug(1201) << "KonqSidebarTree::scanDir executing " << cp << endl; + ::system( QFile::encodeName(cp) ); + } + } + } + } + // hack to make QDir refresh the lists + dir.setPath(path); + entries = dir.entryList( QDir::Files ); + dirEntries = dir.entryList( QDir::Dirs ); + dirEntries.remove( "." ); + dirEntries.remove( ".." ); + } + } + QStringList::ConstIterator eIt = entries.begin(); + QStringList::ConstIterator eEnd = entries.end(); + + for (; eIt != eEnd; ++eIt ) + { + QString filePath = QString( *eIt ).prepend( path ); + KURL u; + u.setPath( filePath ); + if ( KMimeType::findByURL( u, 0, true )->name() == "application/x-desktop" ) + loadTopLevelItem( parent, filePath ); + } + + eIt = dirEntries.begin(); + eEnd = dirEntries.end(); + + for (; eIt != eEnd; eIt++ ) + { + QString newPath = QString( path ).append( *eIt ).append( '/' ); + + if ( newPath == KGlobalSettings::autostartPath() ) + continue; + + loadTopLevelGroup( parent, newPath ); + } +} + +void KonqSidebarTree::loadTopLevelGroup( KonqSidebarTreeItem *parent, const QString &path ) +{ + QDir dir( path ); + QString name = dir.dirName(); + QString icon = "folder"; + bool open = false; + + kdDebug(1201) << "Scanning " << path << endl; + + QString dotDirectoryFile = QString( path ).append( "/.directory" ); + + if ( QFile::exists( dotDirectoryFile ) ) + { + kdDebug(1201) << "Reading the .directory" << endl; + KSimpleConfig cfg( dotDirectoryFile, true ); + cfg.setDesktopGroup(); + name = cfg.readEntry( "Name", name ); + icon = cfg.readEntry( "Icon", icon ); + //stripIcon( icon ); + open = cfg.readBoolEntry( "Open", open ); + } + + KonqSidebarTreeTopLevelItem *item; + if ( parent ) + { + kdDebug(1201) << "KonqSidebarTree::loadTopLevelGroup Inserting new group under parent " << endl; + item = new KonqSidebarTreeTopLevelItem( parent, 0 /* no module */, path ); + } + else + item = new KonqSidebarTreeTopLevelItem( this, 0 /* no module */, path ); + item->setText( 0, name ); + item->setPixmap( 0, SmallIcon( icon ) ); + item->setListable( false ); + item->setClickable( false ); + item->setTopLevelGroup( true ); + item->setOpen( open ); + + m_topLevelItems.append( item ); + + kdDebug(1201) << "Inserting group " << name << " " << path << endl; + + scanDir( item, path ); + + if ( item->childCount() == 0 ) + item->setExpandable( false ); +} + +void KonqSidebarTree::loadTopLevelItem( KonqSidebarTreeItem *parent, const QString &filename ) +{ + KDesktopFile cfg( filename, true ); + cfg.setDollarExpansion(true); + + QFileInfo inf( filename ); + + QString path = filename; + QString name = KIO::decodeFileName( inf.fileName() ); + if ( name.length() > 8 && name.right( 8 ) == ".desktop" ) + name.truncate( name.length() - 8 ); + if ( name.length() > 7 && name.right( 7 ) == ".kdelnk" ) + name.truncate( name.length() - 7 ); + + name = cfg.readEntry( "Name", name ); + KonqSidebarTreeModule * module = 0L; + + // Here's where we need to create the right module... + // ### TODO: make this KTrader/KLibrary based. + QString moduleName = cfg.readEntry( "X-KDE-TreeModule" ); + QString showHidden=cfg.readEntry("X-KDE-TreeModule-ShowHidden"); + + if (moduleName.isEmpty()) moduleName="Directory"; + kdDebug(1201) << "##### Loading module: " << moduleName << " file: " << filename << endl; + + getModule func; + func = getPluginFactory(moduleName); + if (func!=0) + { + kdDebug(1201)<<"showHidden: "<<showHidden<<endl; + module=func(this,showHidden.upper()=="TRUE"); + } + + if (module==0) {kdDebug()<<"No Module loaded"<<endl; return;} + + KonqSidebarTreeTopLevelItem *item; + if ( parent ) + item = new KonqSidebarTreeTopLevelItem( parent, module, path ); + else + item = new KonqSidebarTreeTopLevelItem( this, module, path ); + + item->setText( 0, name ); + item->setPixmap( 0, SmallIcon( cfg.readIcon() )); + + module->addTopLevelItem( item ); + + m_topLevelItems.append( item ); + m_lstModules.append( module ); + + bool open = cfg.readBoolEntry( "Open", false ); + if ( open && item->isExpandable() ) + item->setOpen( true ); +} + +void KonqSidebarTree::slotAnimation() +{ + MapCurrentOpeningFolders::Iterator it = m_mapCurrentOpeningFolders.begin(); + MapCurrentOpeningFolders::Iterator end = m_mapCurrentOpeningFolders.end(); + for (; it != end; ++it ) + { + uint & iconNumber = it.data().iconNumber; + QString icon = QString::fromLatin1( it.data().iconBaseName ).append( QString::number( iconNumber ) ); + it.key()->setPixmap( 0, SmallIcon( icon)); + + iconNumber++; + if ( iconNumber > it.data().iconCount ) + iconNumber = 1; + } +} + + +void KonqSidebarTree::startAnimation( KonqSidebarTreeItem * item, const char * iconBaseName, uint iconCount, const QPixmap * originalPixmap ) +{ + const QPixmap *pix = originalPixmap ? originalPixmap : item->pixmap(0); + if (pix) + { + m_mapCurrentOpeningFolders.insert( item, AnimationInfo( iconBaseName, iconCount, *pix ) ); + if ( !m_animationTimer->isActive() ) + m_animationTimer->start( 50 ); + } +} + +void KonqSidebarTree::stopAnimation( KonqSidebarTreeItem * item ) +{ + MapCurrentOpeningFolders::Iterator it = m_mapCurrentOpeningFolders.find(item); + if ( it != m_mapCurrentOpeningFolders.end() ) + { + item->setPixmap( 0, it.data().originalPixmap ); + m_mapCurrentOpeningFolders.remove( item ); + + if (m_mapCurrentOpeningFolders.isEmpty()) + m_animationTimer->stop(); + } +} + +KonqSidebarTreeItem * KonqSidebarTree::currentItem() const +{ + return static_cast<KonqSidebarTreeItem *>( selectedItem() ); +} + +void KonqSidebarTree::setContentsPos( int x, int y ) +{ + if ( !m_scrollingLocked ) + KListView::setContentsPos( x, y ); +} + +void KonqSidebarTree::slotItemRenamed(QListViewItem* item, const QString &name, int col) +{ + Q_ASSERT(col==0); + if (col != 0) return; + assert(item); + KonqSidebarTreeItem * treeItem = static_cast<KonqSidebarTreeItem *>(item); + treeItem->rename( name ); +} + + +void KonqSidebarTree::enableActions( bool copy, bool cut, bool paste, + bool trash, bool del, bool rename) +{ + enableAction( "copy", copy ); + enableAction( "cut", cut ); + enableAction( "paste", paste ); + enableAction( "trash", trash ); + enableAction( "del", del ); + enableAction( "rename", rename ); +} + +bool KonqSidebarTree::tabSupport() +{ + // see if the newTab() dcop function is available (i.e. the sidebar is embedded into konqueror) + DCOPRef ref(kapp->dcopClient()->appId(), topLevelWidget()->name()); + DCOPReply reply = ref.call("functions()"); + if (reply.isValid()) { + QCStringList funcs; + reply.get(funcs, "QCStringList"); + for (QCStringList::ConstIterator it = funcs.begin(); it != funcs.end(); ++it) { + if ((*it) == "void newTab(QString url)") { + return true; + break; + } + } + } + return false; +} + +void KonqSidebarTree::showToplevelContextMenu() +{ + KonqSidebarTreeTopLevelItem *item = 0; + KonqSidebarTreeItem *treeItem = currentItem(); + if (treeItem && treeItem->isTopLevelItem()) + item = static_cast<KonqSidebarTreeTopLevelItem *>(treeItem); + + if (!m_collection) + { + m_collection = new KActionCollection( this, "bookmark actions" ); + (void) new KAction( i18n("&Create New Folder..."), "folder_new", 0, this, + SLOT( slotCreateFolder() ), m_collection, "create_folder"); + (void) new KAction( i18n("Delete Folder"), "editdelete", 0, this, + SLOT( slotDelete() ), m_collection, "delete_folder"); + (void) new KAction( i18n("Rename"), 0, this, + SLOT( slotRename() ), m_collection, "rename"); + (void) new KAction( i18n("Delete Link"), "editdelete", 0, this, + SLOT( slotDelete() ), m_collection, "delete_link"); + (void) new KAction( i18n("Properties"), "edit", 0, this, + SLOT( slotProperties() ), m_collection, "item_properties"); + (void) new KAction( i18n("Open in New Window"), "window_new", 0, this, + SLOT( slotOpenNewWindow() ), m_collection, "open_window"); + (void) new KAction( i18n("Open in New Tab"), "tab_new", 0, this, + SLOT( slotOpenTab() ), m_collection, "open_tab"); + (void) new KAction( i18n("Copy Link Address"), "editcopy", 0, this, + SLOT( slotCopyLocation() ), m_collection, "copy_location"); + } + + QPopupMenu *menu = new QPopupMenu; + + if (item) { + if (item->isTopLevelGroup()) { + m_collection->action("rename")->plug(menu); + m_collection->action("delete_folder")->plug(menu); + menu->insertSeparator(); + m_collection->action("create_folder")->plug(menu); + } else { + if (tabSupport()) + m_collection->action("open_tab")->plug(menu); + m_collection->action("open_window")->plug(menu); + m_collection->action("copy_location")->plug(menu); + menu->insertSeparator(); + m_collection->action("rename")->plug(menu); + m_collection->action("delete_link")->plug(menu); + } + menu->insertSeparator(); + m_collection->action("item_properties")->plug(menu); + } else { + m_collection->action("create_folder")->plug(menu); + } + + m_currentTopLevelItem = item; + + menu->exec( QCursor::pos() ); + delete menu; + + m_currentTopLevelItem = 0; +} + +void KonqSidebarTree::slotCreateFolder() +{ + QString path; + QString name = i18n("New Folder"); + + while(true) + { + name = KInputDialog::getText(i18n("Create New Folder"), + i18n("Enter folder name:"), name); + if (name.isEmpty()) + return; + + if (m_currentTopLevelItem) + path = m_currentTopLevelItem->path(); + else + path = m_dirtreeDir.dir.path(); + + if (!path.endsWith("/")) + path += "/"; + + path = path + name; + + if (!QFile::exists(path)) + break; + + name = name + "-2"; + } + + KGlobal::dirs()->makeDir(path); + + loadTopLevelGroup(m_currentTopLevelItem, path); +} + +void KonqSidebarTree::slotDelete() +{ + if (!m_currentTopLevelItem) return; + m_currentTopLevelItem->del(); +} + +void KonqSidebarTree::slotRename() +{ + if (!m_currentTopLevelItem) return; + m_currentTopLevelItem->rename(); +} + +void KonqSidebarTree::slotProperties() +{ + if (!m_currentTopLevelItem) return; + + KURL url; + url.setPath(m_currentTopLevelItem->path()); + + KPropertiesDialog *dlg = new KPropertiesDialog( url ); + dlg->setFileNameReadOnly(true); + dlg->exec(); + delete dlg; +} + +void KonqSidebarTree::slotOpenNewWindow() +{ + if (!m_currentTopLevelItem) return; + emit createNewWindow( m_currentTopLevelItem->externalURL() ); +} + +void KonqSidebarTree::slotOpenTab() +{ + if (!m_currentTopLevelItem) return; + DCOPRef ref(kapp->dcopClient()->appId(), topLevelWidget()->name()); + ref.call( "newTab(QString)", m_currentTopLevelItem->externalURL().url() ); +} + +void KonqSidebarTree::slotCopyLocation() +{ + if (!m_currentTopLevelItem) return; + KURL url = m_currentTopLevelItem->externalURL(); + kapp->clipboard()->setData( new KURLDrag(url, 0), QClipboard::Selection ); + kapp->clipboard()->setData( new KURLDrag(url, 0), QClipboard::Clipboard ); +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + +void KonqSidebarTreeToolTip::maybeTip( const QPoint &point ) +{ + QListViewItem *item = m_view->itemAt( point ); + if ( item ) { + QString text = static_cast<KonqSidebarTreeItem*>( item )->toolTipText(); + if ( !text.isEmpty() ) + tip ( m_view->itemRect( item ), text ); + } +} + + + + +#include "konq_sidebartree.moc" diff --git a/konqueror/sidebar/trees/konq_sidebartree.h b/konqueror/sidebar/trees/konq_sidebartree.h new file mode 100644 index 000000000..cc2035466 --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartree.h @@ -0,0 +1,225 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + 2000 Carsten Pfeiffer <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef konq_tree_h +#define konq_tree_h + +#include <klistview.h> +#include "konq_sidebartreetoplevelitem.h" +#include "konqsidebar_tree.h" +#include <kdirnotify.h> +#include <qmap.h> +#include <qpoint.h> +#include <qstrlist.h> +#include <qtooltip.h> + +class KonqSidebarTreeModule; +class KonqSidebarTreeItem; +class KActionCollection; + +class QTimer; + +class KonqSidebarTree_Internal; + +#define VIRT_Link 0 +#define VIRT_Folder 1 // A directory which is parsed for .desktop files + +typedef KonqSidebarTreeModule*(*getModule)(KonqSidebarTree*, const bool); + +typedef struct DirTreeConfigData_ +{ + KURL dir; + int type; + QString relDir; +} DirTreeConfigData; + + +class KonqSidebarTreeToolTip : public QToolTip +{ +public: + KonqSidebarTreeToolTip( QListView *view ) : QToolTip( view->viewport() ), m_view( view ) {} + +protected: + virtual void maybeTip( const QPoint & ); + +private: + QListView *m_view; +}; + +typedef enum { + SidebarTreeMode, // used if the drop is accepted by a KonqSidebarTreeItem. otherwise + KListViewMode // use KListView's dnd implementation. accepts mime types set with setDropFormats() +} DropAcceptType; + +/** + * The multi-purpose tree (listview) + * It parses its configuration (desktop files), each one corresponding to + * a toplevel item, and creates the modules that will handle the contents + * of those items. + */ +class KonqSidebarTree : public KListView, public KDirNotify +{ + Q_OBJECT +public: + KonqSidebarTree( KonqSidebar_Tree *parent, QWidget *parentWidget, int virt, const QString& path ); + virtual ~KonqSidebarTree(); + + void followURL( const KURL &url ); + + /** + * @return the current (i.e. selected) item + */ + KonqSidebarTreeItem * currentItem() const; + + void startAnimation( KonqSidebarTreeItem * item, const char * iconBaseName = "kde", uint iconCount = 6, const QPixmap * originalPixmap = 0L ); + void stopAnimation( KonqSidebarTreeItem * item ); + + // Reimplemented from KDirNotify + void FilesAdded( const KURL & dir ); + void FilesRemoved( const KURL::List & urls ); + void FilesChanged( const KURL::List & urls ); + + KonqSidebarPlugin * part() { return m_part; } + + void lockScrolling( bool lock ) { m_scrollingLocked = lock; } + + bool isOpeningFirstChild() const { return m_bOpeningFirstChild; } + + void enableActions( bool copy, bool cut, bool paste, + bool trash, bool del, bool rename = false ); + + void itemDestructed( KonqSidebarTreeItem *item ); + + void setDropFormats( const QStringList &formats ); // used in KListView mode + + // Show context menu for toplevel items + void showToplevelContextMenu(); + + // Add an URL + void addURL(KonqSidebarTreeTopLevelItem* item, const KURL&url); + + // If we can use dcop to open tabs + bool tabSupport(); + +public slots: + virtual void setContentsPos( int x, int y ); + +protected: + virtual void contentsDragEnterEvent( QDragEnterEvent *e ); + virtual void contentsDragMoveEvent( QDragMoveEvent *e ); + virtual void contentsDragLeaveEvent( QDragLeaveEvent *e ); + virtual void contentsDropEvent( QDropEvent *ev ); + virtual bool acceptDrag(QDropEvent* e) const; // used in KListView mode + + virtual void leaveEvent( QEvent * ); + + virtual QDragObject* dragObject(); + +private slots: + void slotDoubleClicked( QListViewItem *item ); + void slotExecuted( QListViewItem *item ); + void slotMouseButtonPressed(int _button, QListViewItem* _item, const QPoint&, int col); + void slotMouseButtonClicked(int _button, QListViewItem* _item, const QPoint&, int col); + void slotSelectionChanged(); + + void slotAnimation(); + + void slotAutoOpenFolder(); + + void rescanConfiguration(); + + void slotItemRenamed(QListViewItem*, const QString &, int); + + void slotCreateFolder(); + void slotDelete(); + void slotRename(); + void slotProperties(); + void slotOpenNewWindow(); + void slotOpenTab(); + void slotCopyLocation(); + +private: + void clearTree(); + void scanDir( KonqSidebarTreeItem *parent, const QString &path, bool isRoot = false ); + void loadTopLevelGroup( KonqSidebarTreeItem *parent, const QString &path ); + void loadTopLevelItem( KonqSidebarTreeItem *parent, const QString &filename ); + + void loadModuleFactories(); + + +private: + QPtrList<KonqSidebarTreeTopLevelItem> m_topLevelItems; + KonqSidebarTreeTopLevelItem *m_currentTopLevelItem; + + QPtrList<KonqSidebarTreeModule> m_lstModules; + + KonqSidebarPlugin *m_part; + + struct AnimationInfo + { + AnimationInfo( const char * _iconBaseName, uint _iconCount, const QPixmap & _originalPixmap ) + : iconBaseName(_iconBaseName), iconCount(_iconCount), iconNumber(1), originalPixmap(_originalPixmap) {} + AnimationInfo() : iconCount(0) {} + QCString iconBaseName; + uint iconCount; + uint iconNumber; + QPixmap originalPixmap; + }; + typedef QMap<KonqSidebarTreeItem *, AnimationInfo> MapCurrentOpeningFolders; + MapCurrentOpeningFolders m_mapCurrentOpeningFolders; + + QTimer *m_animationTimer; + + QListViewItem *m_currentBeforeDropItem; // The item that was current before the drag-enter event happened + QListViewItem *m_dropItem; // The item we are moving the mouse over (during a drag) + QStrList m_lstDropFormats; + + QTimer *m_autoOpenTimer; + + // The base URL for our configuration directory + //KURL m_dirtreeDir; + DirTreeConfigData m_dirtreeDir; + + KonqSidebarTreeToolTip m_toolTip; + bool m_scrollingLocked; + + getModule getPluginFactory(QString name); + + QMap<QString, QString> pluginInfo; + QMap<QString, getModule> pluginFactories; + + bool m_bOpeningFirstChild; + KActionCollection *m_collection; + + KonqSidebarTree_Internal *d; + +#undef signals +#define signals public +signals: +#undef signals +#define signals protected + void openURLRequest( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + void createNewWindow( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + void popupMenu( const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode = (mode_t)-1 ); + void popupMenu( const QPoint &global, const KFileItemList &items ); + void enableAction( const char * name, bool enabled ); +}; + +#endif diff --git a/konqueror/sidebar/trees/konq_sidebartreeitem.cpp b/konqueror/sidebar/trees/konq_sidebartreeitem.cpp new file mode 100644 index 000000000..daa0ae777 --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartreeitem.cpp @@ -0,0 +1,65 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include "konq_sidebartree.h" +//#include "konq_sidebartreepart.h" + +KonqSidebarTreeItem::KonqSidebarTreeItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem ) + : QListViewItem( parentItem ) +{ + initItem( topLevelItem ); +} + +KonqSidebarTreeItem::KonqSidebarTreeItem( KonqSidebarTree *parent, KonqSidebarTreeTopLevelItem *topLevelItem ) + : QListViewItem( parent ) +{ + initItem( topLevelItem ); +} + +KonqSidebarTreeItem::~KonqSidebarTreeItem() +{ + KonqSidebarTree *t = tree(); + if (t) + t->itemDestructed(this); +} + +void KonqSidebarTreeItem::initItem( KonqSidebarTreeTopLevelItem *topLevelItem ) +{ + m_topLevelItem = topLevelItem; + m_bListable = true; + m_bClickable = true; + + setExpandable( true ); +} + +void KonqSidebarTreeItem::middleButtonClicked() +{ + emit tree()->createNewWindow( externalURL() ); +} + +KonqSidebarTreeModule * KonqSidebarTreeItem::module() const +{ + return m_topLevelItem->module(); +} + +KonqSidebarTree * KonqSidebarTreeItem::tree() const +{ + return static_cast<KonqSidebarTree *>(listView()); +} diff --git a/konqueror/sidebar/trees/konq_sidebartreeitem.h b/konqueror/sidebar/trees/konq_sidebartreeitem.h new file mode 100644 index 000000000..ef6f73931 --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartreeitem.h @@ -0,0 +1,116 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef konq_treeitem_h +#define konq_treeitem_h + +#include <qlistview.h> +#include <qstringlist.h> +#include <kurl.h> + +class QPainter; +class QDragObject; +class QStrList; +class KonqSidebarTree; +class KonqSidebarTreeItem; +class KonqSidebarTreeModule; +class KonqSidebarTreeTopLevelItem; + +/** + * The base class for any item in the tree. + * Items belonging to a given module are created and managed by the module, + * but they should all be KonqSidebarTreeItems, for the event handling in KonqSidebarTree. + */ +class KonqSidebarTreeItem : public QListViewItem +{ +public: + // Create an item under another one + KonqSidebarTreeItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem ); + + void initItem( KonqSidebarTreeTopLevelItem *topLevelItem ); + + virtual ~KonqSidebarTreeItem(); + + // Whether the item accepts a drop consisting in those @p formats + virtual bool acceptsDrops( const QStrList & ) { return false; } + + // Handle a drop on this item. If you didn't want it, you shouln't + // have return true in acceptsDrops :) + virtual void drop( QDropEvent * ) {} + + // Create a drag object from this item. + virtual QDragObject * dragObject( QWidget * parent, bool move = false ) = 0; + + virtual void middleButtonClicked(); + virtual void rightButtonPressed() = 0; + + virtual void paste() {} + virtual void trash() {} + virtual void del() {} + virtual void shred() {} + virtual void rename() {} + virtual void rename( const QString& ) {} + + // The URL to open when this link is clicked + virtual KURL externalURL() const = 0; + + // The mimetype to use when this link is clicked + // If unknown, return QString::null, konq will determine the mimetype itself + virtual QString externalMimeType() const { return QString::null; } + + // overwrite this if you want a tooltip shown on your item + virtual QString toolTipText() const { return QString::null; } + + // Called when this item is selected + // Reimplement, and call tree()->part()->extension()->enableActions(...) + virtual void itemSelected() = 0; + + // Basically, true for directories and toplevel items + void setListable( bool b ) { m_bListable = b; } + bool isListable() const { return m_bListable; } + + // Whether clicking on the item should open the "external URL" of the item + void setClickable( bool b ) { m_bClickable = b; } + bool isClickable() const { return m_bClickable; } + + // Whether the item is a toplevel item + virtual bool isTopLevelItem() const { return false; } + + KonqSidebarTreeTopLevelItem * topLevelItem() const { return m_topLevelItem; } + + // returns the module associated to our toplevel item + KonqSidebarTreeModule * module() const; + + // returns the tree inside which this item is + KonqSidebarTree *tree() const; + + virtual QString key( int column, bool ) const { return text( column ).lower(); } + + // List of alternative names (URLs) this entry is known under + QStringList alias; +protected: + // Create an item at the toplevel - only for toplevel items -> protected + KonqSidebarTreeItem( KonqSidebarTree *parent, KonqSidebarTreeTopLevelItem *topLevelItem ); + + KonqSidebarTreeTopLevelItem *m_topLevelItem; + bool m_bListable:1; + bool m_bClickable:1; +}; + +#endif diff --git a/konqueror/sidebar/trees/konq_sidebartreemodule.h b/konqueror/sidebar/trees/konq_sidebartreemodule.h new file mode 100644 index 000000000..9f9863311 --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartreemodule.h @@ -0,0 +1,65 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef konq_treemodule_h +#define konq_treemodule_h + +#include <qobject.h> +#include "konq_sidebartree.h" +class QDragObject; +class KonqSidebarTreeItem; +class KonqSidebarTreeTopLevelItem; +class KonqSidebarTree; + +/** + * The base class for KonqSidebarTree Modules. It defines the interface + * between the generic KonqSidebarTree and the particular modules + * (directory tree, history, bookmarks, ...) + */ +class KonqSidebarTreeModule +{ +public: + KonqSidebarTreeModule( KonqSidebarTree * parentTree , bool showHidden=false) + : m_pTree( parentTree ), m_showHidden(showHidden) {} + virtual ~KonqSidebarTreeModule() {} + + // Handle this new toplevel item [can only be called once currently] + virtual void addTopLevelItem( KonqSidebarTreeTopLevelItem * item ) = 0; + + // Open this toplevel item - you don't need to reimplement if + // you create the item's children right away + virtual void openTopLevelItem( KonqSidebarTreeTopLevelItem * ) {} + + // Follow a URL opened in another view - only implement if the module + // has anything to do with URLs + virtual void followURL( const KURL & ) {} + + KonqSidebarTree *tree() const { return m_pTree; } + bool showHidden() { return m_showHidden;} + virtual void setShowHidden(bool showhidden) {m_showHidden=showhidden;} + + virtual bool handleTopLevelContextMenu( KonqSidebarTreeTopLevelItem *, const QPoint& ) { return false; } + +protected: + KonqSidebarTree * m_pTree; + bool m_showHidden; +}; + + + +#endif diff --git a/konqueror/sidebar/trees/konq_sidebartreetoplevelitem.cpp b/konqueror/sidebar/trees/konq_sidebartreetoplevelitem.cpp new file mode 100644 index 000000000..d71959c1e --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartreetoplevelitem.cpp @@ -0,0 +1,208 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +//#include "konq_treepart.h" +#include "konq_sidebartreemodule.h" +#include <kdebug.h> +#include <kdirnotify_stub.h> +#include <kio/paste.h> +#include <konq_operations.h> +#include <kprotocolinfo.h> +#include <kurldrag.h> +#include <kmimetype.h> +#include <qapplication.h> +#include <qclipboard.h> +#include <qcursor.h> +#include <konq_drag.h> + +void KonqSidebarTreeTopLevelItem::init() +{ + QString desktopFile = m_path; + if ( isTopLevelGroup() ) + desktopFile += "/.directory"; + KSimpleConfig cfg( desktopFile, true ); + cfg.setDesktopGroup(); + m_comment = cfg.readEntry( "Comment" ); +} + +void KonqSidebarTreeTopLevelItem::setOpen( bool open ) +{ + if (open && module()) + module()->openTopLevelItem( this ); + KonqSidebarTreeItem::setOpen( open ); +} + +void KonqSidebarTreeTopLevelItem::itemSelected() +{ + kdDebug() << "KonqSidebarTreeTopLevelItem::itemSelected" << endl; + QMimeSource *data = QApplication::clipboard()->data(); + bool paste = m_bTopLevelGroup && data->provides("text/uri-list"); + tree()->enableActions( true, true, paste, true, true, true /*rename*/ ); +} + +bool KonqSidebarTreeTopLevelItem::acceptsDrops( const QStrList & formats ) +{ + return formats.contains("text/uri-list") && + ( m_bTopLevelGroup || !externalURL().isEmpty() ); +} + +void KonqSidebarTreeTopLevelItem::drop( QDropEvent * ev ) +{ + if ( m_bTopLevelGroup ) + { + // When dropping something to "Network" or its subdirs, we want to create + // a desktop link, not to move/copy/link - except for .desktop files :-} + KURL::List lst; + if ( KURLDrag::decode( ev, lst ) && !lst.isEmpty() ) // Are they urls ? + { + KURL::List::Iterator it = lst.begin(); + for ( ; it != lst.end() ; it++ ) + { + tree()->addURL(this, *it); + } + } else + kdError(1202) << "No URL !? " << endl; + } + else // Top level item, not group + { + if ( !externalURL().isEmpty() ) + KonqOperations::doDrop( 0L, externalURL(), ev, tree() ); + } +} + +QDragObject * KonqSidebarTreeTopLevelItem::dragObject( QWidget * parent, bool move ) +{ + // 100% duplicated from KonqDirTreeItem::dragObject :( + KURL::List lst; + KURL url; + url.setPath( path() ); + lst.append( url ); + + KonqDrag * drag = KonqDrag::newDrag( lst, false, parent ); + + const QPixmap * pix = pixmap(0); + if (pix) + { + QPoint hotspot( pix->width() / 2, pix->height() / 2 ); + drag->setPixmap( *pix, hotspot ); + } + drag->setMoveSelection( move ); + + return drag; +} + +void KonqSidebarTreeTopLevelItem::middleButtonClicked() +{ + if ( !m_bTopLevelGroup ) + emit tree()->createNewWindow( m_externalURL ); + // Do nothing for toplevel groups +} + +void KonqSidebarTreeTopLevelItem::rightButtonPressed() +{ + KURL url; + url.setPath( m_path ); + // We don't show "edit file type" (useless here) and "properties" (shows the wrong name, + // i.e. the filename instead of the Name field). There's the Rename item for that. + // Only missing thing is changing the URL of a link. Hmm... + + if ( !module() || !module()->handleTopLevelContextMenu( this, QCursor::pos() ) ) + { + tree()->showToplevelContextMenu(); + } +} + + +void KonqSidebarTreeTopLevelItem::trash() +{ + delOperation( KonqOperations::TRASH ); +} + +void KonqSidebarTreeTopLevelItem::del() +{ + delOperation( KonqOperations::DEL ); +} + +void KonqSidebarTreeTopLevelItem::shred() +{ + delOperation( KonqOperations::SHRED ); +} + +void KonqSidebarTreeTopLevelItem::delOperation( int method ) +{ + KURL url; + url.setPath( m_path ); + KURL::List lst; + lst.append(url); + + KonqOperations::del(tree(), method, lst); +} + +void KonqSidebarTreeTopLevelItem::paste() +{ + // move or not move ? + bool move = false; + QMimeSource *data = QApplication::clipboard()->data(); + if ( data->provides( "application/x-kde-cutselection" ) ) { + move = KonqDrag::decodeIsCutSelection( data ); + kdDebug(1201) << "move (from clipboard data) = " << move << endl; + } + + KURL destURL; + if ( m_bTopLevelGroup ) + destURL.setPath( m_path ); + else + destURL = m_externalURL; + + KIO::pasteClipboard( destURL, move ); +} + +void KonqSidebarTreeTopLevelItem::rename() +{ + tree()->rename( this, 0 ); +} + +void KonqSidebarTreeTopLevelItem::rename( const QString & name ) +{ + KURL url; + url.setPath( m_path ); + + // Well, it's not really the file we want to rename, it's the Name field + // of the .directory or desktop file + //KonqOperations::rename( tree(), url, name ); + + QString desktopFile = m_path; + if ( isTopLevelGroup() ) + desktopFile += "/.directory"; + KSimpleConfig cfg( desktopFile ); + cfg.setDesktopGroup(); + cfg.writeEntry( "Name", name ); + cfg.sync(); + + // Notify about the change + KURL::List lst; + lst.append(url); + KDirNotify_stub allDirNotify("*", "KDirNotify*"); + allDirNotify.FilesChanged( lst ); +} + +QString KonqSidebarTreeTopLevelItem::toolTipText() const +{ + return m_comment; +} + diff --git a/konqueror/sidebar/trees/konq_sidebartreetoplevelitem.h b/konqueror/sidebar/trees/konq_sidebartreetoplevelitem.h new file mode 100644 index 000000000..fc67e274e --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartreetoplevelitem.h @@ -0,0 +1,101 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef konq_treetoplevelitem_h +#define konq_treetoplevelitem_h + +#include "konq_sidebartreeitem.h" + +class QStrList; +class KonqSidebarTreeModule; + +/** + * Each toplevel item (created from a desktop file) + * points to the module that handles it + --> this doesn't prevent the same module from handling multiple toplevel items, + but we don't do that currently. + */ +class KonqSidebarTreeTopLevelItem : public KonqSidebarTreeItem +{ +public: + /** + * Create a toplevel toplevel-item :) + * @param module the module handling this toplevel item + * @param path the path to the desktop file that was the reason for creating this item + */ + KonqSidebarTreeTopLevelItem( KonqSidebarTree *parent, KonqSidebarTreeModule * module, const QString & path ) + : KonqSidebarTreeItem(parent, 0L), m_module(module), m_path(path), m_bTopLevelGroup(false) { init(); } + + /** + * Create a toplevel-item under a toplevel group + * @param module the module handling this toplevel item + * @param path the path to the desktop file that was the reason for creating this item + */ + KonqSidebarTreeTopLevelItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeModule * module, const QString & path ) + : KonqSidebarTreeItem( parentItem, 0L), m_module(module), m_path(path), m_bTopLevelGroup(false) { init(); } + + void init(); + + virtual bool acceptsDrops( const QStrList & formats ); + virtual void drop( QDropEvent * ev ); + virtual QDragObject * dragObject( QWidget * parent, bool move = false ); + virtual void middleButtonClicked(); + virtual void rightButtonPressed(); + + virtual void paste(); + virtual void trash(); + virtual void del(); + virtual void shred(); + virtual void rename(); // start a rename operation + virtual void rename( const QString & name ); // do the actual renaming + + virtual void setOpen( bool open ); + + // Whether the item is a toplevel item - true + virtual bool isTopLevelItem() const { return true; } + + virtual KURL externalURL() const { return m_externalURL; } + + virtual QString toolTipText() const; + + virtual void itemSelected(); + + // The module should call this for each toplevel item that is passed to it + // unless it calls setClickable(false) + void setExternalURL( const KURL & url ) { m_externalURL = url; } + + // Whether the item is a toplevel group. [Only matters for dnd] + void setTopLevelGroup( bool b ) { m_bTopLevelGroup = b; } + bool isTopLevelGroup() const { return m_bTopLevelGroup; } + + // The module that handles the subtree below this toplevel item + KonqSidebarTreeModule *module() const { return m_module; } + + // The path to the desktop file responsible for this toplevel item + QString path() const { return m_path; } + +protected: + void delOperation( int method ); + KonqSidebarTreeModule *m_module; + QString m_path; + QString m_comment; + KURL m_externalURL; + bool m_bTopLevelGroup; +}; + +#endif diff --git a/konqueror/sidebar/trees/konqsidebar_tree.cpp b/konqueror/sidebar/trees/konqsidebar_tree.cpp new file mode 100644 index 000000000..9b53f195d --- /dev/null +++ b/konqueror/sidebar/trees/konqsidebar_tree.cpp @@ -0,0 +1,167 @@ +#include "konqsidebar_tree.h" +#include "konqsidebar_tree.moc" +#include "konq_sidebartree.h" +#include <kdebug.h> +#include <kstandarddirs.h> +#include <ksimpleconfig.h> +#include <kinputdialog.h> +#include <kiconloader.h> +#include <klistviewsearchline.h> + +#include <qclipboard.h> +#include <qdragobject.h> +#include <qtoolbutton.h> +#include <qvbox.h> + +KonqSidebar_Tree::KonqSidebar_Tree(KInstance *instance,QObject *parent,QWidget *widgetParent, QString &desktopName_, const char* name): + KonqSidebarPlugin(instance,parent,widgetParent,desktopName_,name) + { + KSimpleConfig ksc(desktopName_); + ksc.setGroup("Desktop Entry"); + int virt= ( (ksc.readEntry("X-KDE-TreeModule","")=="Virtual") ?VIRT_Folder:VIRT_Link); + if (virt==1) desktopName_=ksc.readEntry("X-KDE-RelURL",""); + + widget = new QVBox(widgetParent); + + if (ksc.readBoolEntry("X-KDE-SearchableTreeModule",false)) { + QHBox* searchline = new QHBox(widget); + searchline->setSpacing(KDialog::spacingHint()); + tree=new KonqSidebarTree(this,widget,virt,desktopName_); + QToolButton *clearSearch = new QToolButton(searchline); + clearSearch->setTextLabel(i18n("Clear Search"), true); + clearSearch->setIconSet(SmallIconSet(QApplication::reverseLayout() ? "clear_left" : "locationbar_erase")); + QLabel* slbl = new QLabel(i18n("Se&arch:"), searchline); + KListViewSearchLine* listViewSearch = new KListViewSearchLine(searchline,tree); + slbl->setBuddy(listViewSearch); + connect(clearSearch, SIGNAL(pressed()), listViewSearch, SLOT(clear())); + } + else + tree=new KonqSidebarTree(this,widget,virt,desktopName_); + + connect(tree, SIGNAL( openURLRequest( const KURL &, const KParts::URLArgs &)), + this,SIGNAL( openURLRequest( const KURL &, const KParts::URLArgs &))); + + connect(tree,SIGNAL(createNewWindow( const KURL &, const KParts::URLArgs &)), + this,SIGNAL(createNewWindow( const KURL &, const KParts::URLArgs &))); + + connect(tree,SIGNAL(popupMenu( const QPoint &, const KURL &, const QString &, mode_t )), + this,SIGNAL(popupMenu( const QPoint &, const KURL &, const QString &, mode_t ))); + + connect(tree,SIGNAL(popupMenu( const QPoint &, const KFileItemList & )), + this,SIGNAL(popupMenu( const QPoint &, const KFileItemList & ))); + + connect(tree,SIGNAL(enableAction( const char *, bool )), + this,SIGNAL(enableAction( const char *, bool))); + + } + + +KonqSidebar_Tree::~KonqSidebar_Tree(){;} + +void* KonqSidebar_Tree::provides(const QString &) {return 0;} + +//void KonqSidebar_Tree::emitStatusBarText (const QString &) {;} + +QWidget *KonqSidebar_Tree::getWidget(){return widget;} + +void KonqSidebar_Tree::handleURL(const KURL &url) + { + emit started( 0 ); + tree->followURL( url ); + emit completed(); + } + +void KonqSidebar_Tree::cut() +{ + QDragObject * drag = static_cast<KonqSidebarTreeItem*>(tree->selectedItem())->dragObject( 0L, true ); + if (drag) + QApplication::clipboard()->setData( drag ); +} + +void KonqSidebar_Tree::copy() +{ + QDragObject * drag = static_cast<KonqSidebarTreeItem*>(tree->selectedItem())->dragObject( 0L ); + if (drag) + QApplication::clipboard()->setData( drag ); +} + +void KonqSidebar_Tree::paste() +{ + if (tree->currentItem()) + tree->currentItem()->paste(); +} + +void KonqSidebar_Tree::trash() +{ + if (tree->currentItem()) + tree->currentItem()->trash(); +} + +void KonqSidebar_Tree::del() +{ + if (tree->currentItem()) + tree->currentItem()->del(); +} + +void KonqSidebar_Tree::shred() +{ + if (tree->currentItem()) + tree->currentItem()->shred(); +} + +void KonqSidebar_Tree::rename() +{ + Q_ASSERT( tree->currentItem() ); + if (tree->currentItem()) + tree->currentItem()->rename(); +} + + + + + + +extern "C" +{ + KDE_EXPORT void* create_konqsidebar_tree(KInstance *inst,QObject *par,QWidget *widp,QString &desktopname,const char *name) + { + return new KonqSidebar_Tree(inst,par,widp,desktopname,name); + } +} + +extern "C" +{ + KDE_EXPORT bool add_konqsidebar_tree(QString* fn, QString*, QMap<QString,QString> *map) + { + KStandardDirs *dirs=KGlobal::dirs(); + QStringList list=dirs->findAllResources("data","konqsidebartng/dirtree/*.desktop",false,true); + QStringList names; + for (QStringList::ConstIterator it=list.begin();it!=list.end();++it) + { + KSimpleConfig sc(*it); + sc.setGroup("Desktop Entry"); + names<<sc.readEntry("Name"); + } + + QString item = KInputDialog::getItem( i18n( "Select Type" ), + i18n( "Select type:" ), names ); + if (!item.isEmpty()) + { + int id=names.findIndex( item ); + if (id==-1) return false; + KSimpleConfig ksc2(*list.at(id)); + ksc2.setGroup("Desktop Entry"); + map->insert("Type","Link"); + map->insert("Icon",ksc2.readEntry("Icon")); + map->insert("Name",ksc2.readEntry("Name")); + map->insert("Open","false"); + map->insert("URL",ksc2.readEntry("X-KDE-Default-URL")); + map->insert("X-KDE-KonqSidebarModule","konqsidebar_tree"); + map->insert("X-KDE-TreeModule",ksc2.readEntry("X-KDE-TreeModule")); + map->insert("X-KDE-TreeModule-ShowHidden",ksc2.readEntry("X-KDE-TreeModule-ShowHidden")); + fn->setLatin1("dirtree%1.desktop"); + return true; + } + return false; + } +} diff --git a/konqueror/sidebar/trees/konqsidebar_tree.h b/konqueror/sidebar/trees/konqsidebar_tree.h new file mode 100644 index 000000000..968a59585 --- /dev/null +++ b/konqueror/sidebar/trees/konqsidebar_tree.h @@ -0,0 +1,47 @@ +#ifndef _konq_sidebar_test_h_ +#define _konq_sidebar_test_h_ +#include <konqsidebarplugin.h> +#include <qlabel.h> +#include <qlayout.h> +#include <kparts/part.h> +#include <kparts/factory.h> +#include <kparts/browserextension.h> +#include <kdialogbase.h> +#include <qcombobox.h> +#include <qstringlist.h> +#include <klocale.h> +#include <qlineedit.h> +class KonqSidebarTree; +class QVBox; + +class KonqSidebar_Tree: public KonqSidebarPlugin + { + Q_OBJECT + public: + KonqSidebar_Tree(KInstance *instance,QObject *parent,QWidget *widgetParent, QString &desktopName_, const char* name=0); + ~KonqSidebar_Tree(); + virtual void *provides(const QString &); +// void emitStatusBarText (const QString &); + virtual QWidget *getWidget(); + protected: + class QVBox *widget; + class KonqSidebarTree *tree; + virtual void handleURL(const KURL &url); + protected slots: + void copy(); + void cut(); + void paste(); + void trash(); + void del(); + void shred(); + void rename(); +signals: + void openURLRequest( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + void createNewWindow( const KURL &url, const KParts::URLArgs &args = KParts::URLArgs() ); + void popupMenu( const QPoint &global, const KURL &url, + const QString &mimeType, mode_t mode = (mode_t)-1 ); + void popupMenu( const QPoint &global, const KFileItemList &items ); + void enableAction( const char * name, bool enabled ); + }; + +#endif diff --git a/konqueror/sidebar/web_module/Makefile.am b/konqueror/sidebar/web_module/Makefile.am new file mode 100644 index 000000000..64675d351 --- /dev/null +++ b/konqueror/sidebar/web_module/Makefile.am @@ -0,0 +1,19 @@ +INCLUDES = -I$(srcdir)/../ -I$(srcdir)/../../../libkonq $(all_includes) + +kde_module_LTLIBRARIES = konqsidebar_web.la + +METASOURCES = AUTO + +konqsidebar_web_la_SOURCES = web_module.cpp +konqsidebar_web_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +konqsidebar_web_la_LIBADD = $(LIB_KPARTS) $(LIB_KHTML) ../libkonqsidebarplugin.la ../../../libkonq/libkonq.la + +#plugindir=$(kde_datadir)/konqsidebartng/entries +#plugin_DATA=websidebar.desktop + +pluginadddir=$(kde_datadir)/konqsidebartng/add +pluginadd_DATA=webmodule_add.desktop + +htmldir=$(kde_datadir)/konqsidebartng/websidebar +html_DATA=websidebar.html + diff --git a/konqueror/sidebar/web_module/TODO b/konqueror/sidebar/web_module/TODO new file mode 100644 index 000000000..abf3260f9 --- /dev/null +++ b/konqueror/sidebar/web_module/TODO @@ -0,0 +1,6 @@ +- Apparently _content works everywhere in Mozilla. Maybe this should go into +KHTMLPart afterall. That would solve the form post problem too. +- Forms don't work. I don't know if they will for a long time since we can't + really filter them with KHTML. +- Allow setting the useragent (only do this in a clean fashion!!) +- Double check the KHTML extensions for security implications. diff --git a/konqueror/sidebar/web_module/web_module.cpp b/konqueror/sidebar/web_module/web_module.cpp new file mode 100644 index 000000000..ab77c40a0 --- /dev/null +++ b/konqueror/sidebar/web_module/web_module.cpp @@ -0,0 +1,220 @@ +/* This file is part of the KDE project + Copyright (C) 2003, George Staikos <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "web_module.h" +#include <qfileinfo.h> +#include <qhbox.h> +#include <qspinbox.h> +#include <qtimer.h> + +#include <dom/html_inline.h> +#include <kdebug.h> +#include <kdialog.h> +#include <kglobal.h> +#include <klocale.h> +#include <konq_pixmapprovider.h> +#include <kparts/browserextension.h> +#include <kstandarddirs.h> + + +KonqSideBarWebModule::KonqSideBarWebModule(KInstance *instance, QObject *parent, QWidget *widgetParent, QString &desktopName, const char* name) + : KonqSidebarPlugin(instance, parent, widgetParent, desktopName, name) +{ + _htmlPart = new KHTMLSideBar(universalMode()); + connect(_htmlPart, SIGNAL(reload()), this, SLOT(reload())); + connect(_htmlPart, SIGNAL(completed()), this, SLOT(pageLoaded())); + connect(_htmlPart, + SIGNAL(setWindowCaption(const QString&)), + this, + SLOT(setTitle(const QString&))); + connect(_htmlPart, + SIGNAL(openURLRequest(const QString&, KParts::URLArgs)), + this, + SLOT(urlClicked(const QString&, KParts::URLArgs))); + connect(_htmlPart->browserExtension(), + SIGNAL(openURLRequest(const KURL&, const KParts::URLArgs&)), + this, + SLOT(formClicked(const KURL&, const KParts::URLArgs&))); + connect(_htmlPart, + SIGNAL(setAutoReload()), this, SLOT( setAutoReload() )); + connect(_htmlPart, + SIGNAL(openURLNewWindow(const QString&, KParts::URLArgs)), + this, + SLOT(urlNewWindow(const QString&, KParts::URLArgs))); + connect(_htmlPart, + SIGNAL(submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&)), + this, + SIGNAL(submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&))); + + _desktopName = desktopName; + + KSimpleConfig ksc(_desktopName); + ksc.setGroup("Desktop Entry"); + reloadTimeout = ksc.readNumEntry("Reload", 0); + _url = ksc.readPathEntry("URL"); + _htmlPart->openURL(_url ); + // Must load this delayed + QTimer::singleShot(0, this, SLOT(loadFavicon())); +} + + +KonqSideBarWebModule::~KonqSideBarWebModule() { + delete _htmlPart; + _htmlPart = 0L; +} + + +QWidget *KonqSideBarWebModule::getWidget() { + return _htmlPart->widget(); +} + +void KonqSideBarWebModule::setAutoReload(){ + KDialogBase dlg(0, "", true, i18n("Set Refresh Timeout (0 disables)"), + KDialogBase::Ok|KDialogBase::Cancel); + QHBox *hbox = dlg.makeHBoxMainWidget(); + + QSpinBox *mins = new QSpinBox( 0, 120, 1, hbox ); + mins->setSuffix( i18n(" min") ); + QSpinBox *secs = new QSpinBox( 0, 59, 1, hbox ); + secs->setSuffix( i18n(" sec") ); + + if( reloadTimeout > 0 ) { + int seconds = reloadTimeout / 1000; + secs->setValue( seconds % 60 ); + mins->setValue( ( seconds - secs->value() ) / 60 ); + } + + if( dlg.exec() == QDialog::Accepted ) { + int msec = ( mins->value() * 60 + secs->value() ) * 1000; + reloadTimeout = msec; + KSimpleConfig ksc(_desktopName); + ksc.setGroup("Desktop Entry"); + ksc.writeEntry("Reload", reloadTimeout); + reload(); + } +} + +void *KonqSideBarWebModule::provides(const QString &) { + return 0L; +} + + +void KonqSideBarWebModule::handleURL(const KURL &) { +} + + +void KonqSideBarWebModule::urlNewWindow(const QString& url, KParts::URLArgs args) +{ + emit createNewWindow(KURL(url), args); +} + + +void KonqSideBarWebModule::urlClicked(const QString& url, KParts::URLArgs args) +{ + emit openURLRequest(KURL(url), args); +} + + +void KonqSideBarWebModule::formClicked(const KURL& url, const KParts::URLArgs& args) +{ + _htmlPart->browserExtension()->setURLArgs(args); + _htmlPart->openURL(url); +} + + +void KonqSideBarWebModule::loadFavicon() { + QString icon = KonqPixmapProvider::iconForURL(_url.url()); + if (icon.isEmpty()) { + KonqFavIconMgr::downloadHostIcon(_url); + icon = KonqPixmapProvider::iconForURL(_url.url()); + } + + if (!icon.isEmpty()) { + emit setIcon(icon); + + KSimpleConfig ksc(_desktopName); + ksc.setGroup("Desktop Entry"); + if (icon != ksc.readPathEntry("Icon")) { + ksc.writePathEntry("Icon", icon); + } + } +} + + +void KonqSideBarWebModule::reload() { + _htmlPart->openURL(_url); +} + + +void KonqSideBarWebModule::setTitle(const QString& title) { + if (!title.isEmpty()) { + emit setCaption(title); + + KSimpleConfig ksc(_desktopName); + ksc.setGroup("Desktop Entry"); + if (title != ksc.readPathEntry("Name")) { + ksc.writePathEntry("Name", title); + } + } +} + + +void KonqSideBarWebModule::pageLoaded() { + if( reloadTimeout > 0 ) { + QTimer::singleShot( reloadTimeout, this, SLOT( reload() ) ); + } +} + + +extern "C" { + KDE_EXPORT KonqSidebarPlugin* create_konqsidebar_web(KInstance *instance, QObject *parent, QWidget *widget, QString &desktopName, const char *name) { + return new KonqSideBarWebModule(instance, parent, widget, desktopName, name); + } +} + + +extern "C" { + KDE_EXPORT bool add_konqsidebar_web(QString* fn, QString* param, QMap<QString,QString> *map) { + Q_UNUSED(param); + KGlobal::dirs()->addResourceType("websidebardata", KStandardDirs::kde_default("data") + "konqsidebartng/websidebar"); + KURL url; + url.setProtocol("file"); + QStringList paths = KGlobal::dirs()->resourceDirs("websidebardata"); + for (QStringList::Iterator i = paths.begin(); i != paths.end(); ++i) { + if (QFileInfo(*i + "websidebar.html").exists()) { + url.setPath(*i + "websidebar.html"); + break; + } + } + + if (url.path().isEmpty()) + return false; + map->insert("Type", "Link"); + map->insert("URL", url.url()); + map->insert("Icon", "netscape"); + map->insert("Name", i18n("Web SideBar Plugin")); + map->insert("Open", "true"); + map->insert("X-KDE-KonqSidebarModule","konqsidebar_web"); + fn->setLatin1("websidebarplugin%1.desktop"); + return true; + } +} + + +#include "web_module.moc" + diff --git a/konqueror/sidebar/web_module/web_module.h b/konqueror/sidebar/web_module/web_module.h new file mode 100644 index 000000000..58650b309 --- /dev/null +++ b/konqueror/sidebar/web_module/web_module.h @@ -0,0 +1,202 @@ +/* This file is part of the KDE project + Copyright (C) 2003 George Staikos <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef web_module_h +#define web_module_h + +#include <assert.h> +#include <khtml_part.h> +#include <kiconloader.h> +#include <klocale.h> +#include <konqsidebarplugin.h> +#include <kpopupmenu.h> +#include <qobject.h> + + +// A wrapper for KHTMLPart to make it behave the way we want it to. +class KHTMLSideBar : public KHTMLPart +{ + Q_OBJECT + public: + KHTMLSideBar(bool universal) : KHTMLPart() { + setStatusMessagesEnabled(false); + setMetaRefreshEnabled(true); + setJavaEnabled(false); + setPluginsEnabled(false); + + setFormNotification(KHTMLPart::Only); + connect(this, + SIGNAL(formSubmitNotification(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&)), + this, + SLOT(formProxy(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&)) + ); + + + _linkMenu = new KPopupMenu(widget(), + "link context menu"); + if (!universal) { + _linkMenu->insertItem(i18n("&Open Link"), + this, SLOT(loadPage())); + _linkMenu->insertItem(i18n("Open in New &Window"), + this, SLOT(loadNewWindow())); + } else { + _linkMenu->insertItem(i18n("Open in New &Window"), + this, SLOT(loadPage())); + } + _menu = new KPopupMenu(widget(), "context menu"); + _menu->insertItem(SmallIcon("reload"), i18n("&Reload"), + this, SIGNAL(reload())); + _menu->insertItem(SmallIcon("reload"), i18n("Set &Automatic Reload"), this, SIGNAL(setAutoReload())); + + connect(this, + SIGNAL(popupMenu(const QString&,const QPoint&)), + this, + SLOT(showMenu(const QString&, const QPoint&))); + + } + virtual ~KHTMLSideBar() {} + + signals: + void submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&); + void openURLRequest(const QString& url, KParts::URLArgs args); + void openURLNewWindow(const QString& url, KParts::URLArgs args); + void reload(); + void setAutoReload(); + + protected: + virtual void urlSelected( const QString &url, int button, + int state, const QString &_target, + KParts::URLArgs args = KParts::URLArgs()) { + if (button == LeftButton ){ + if (_target.lower() == "_self") { + openURL(url); + } else if (_target.lower() == "_blank") { + emit openURLNewWindow(completeURL(url).url(), args); + } else { // isEmpty goes here too + emit openURLRequest(completeURL(url).url(), args); + } + return; + } + if (button == MidButton) { + emit openURLNewWindow(completeURL(url).url(), + args); + return; + } + // A refresh + if (button == 0 && _target.lower() == "_self") { + openURL(completeURL(url)); + return; + } + KHTMLPart::urlSelected(url,button,state,_target,args); + } + + protected slots: + void loadPage() { + emit openURLRequest(completeURL(_lastUrl).url(), + KParts::URLArgs()); + } + + void loadNewWindow() { + emit openURLNewWindow(completeURL(_lastUrl).url(), + KParts::URLArgs()); + } + + void showMenu(const QString& url, const QPoint& pos) { + if (url.isEmpty()) { + _menu->popup(pos); + } else { + _lastUrl = url; + _linkMenu->popup(pos); + } + } + + void formProxy(const char *action, + const QString& url, + const QByteArray& formData, + const QString& target, + const QString& contentType, + const QString& boundary) { + QString t = target.lower(); + QString u; + + if (QCString(action).lower() != "post") { + // GET + KURL kurl = completeURL(url); + kurl.setQuery(formData.data()); + u = kurl.url(); + } else { + u = completeURL(url).url(); + } + + // Some sites seem to use empty targets to send to the + // main frame. + if (t == "_content") { + emit submitFormRequest(action, u, formData, + target, contentType, boundary); + } else if (t.isEmpty() || t == "_self") { + setFormNotification(KHTMLPart::NoNotification); + submitFormProxy(action, u, formData, target, + contentType, boundary); + setFormNotification(KHTMLPart::Only); + } + } + private: + KPopupMenu *_menu, *_linkMenu; + QString _lastUrl; +}; + + + +class KonqSideBarWebModule : public KonqSidebarPlugin +{ + Q_OBJECT + public: + KonqSideBarWebModule(KInstance *instance, QObject *parent, + QWidget *widgetParent, QString &desktopName, + const char *name); + virtual ~KonqSideBarWebModule(); + + virtual QWidget *getWidget(); + virtual void *provides(const QString &); + + signals: + void submitFormRequest(const char*,const QString&,const QByteArray&,const QString&,const QString&,const QString&); + void openURLRequest(const KURL &url, const KParts::URLArgs &args); + void createNewWindow(const KURL &url, const KParts::URLArgs &args); + protected: + virtual void handleURL(const KURL &url); + + private slots: + void urlClicked(const QString& url, KParts::URLArgs args); + void formClicked(const KURL& url, const KParts::URLArgs& args); + void urlNewWindow(const QString& url, KParts::URLArgs args); + void pageLoaded(); + void loadFavicon(); + void setTitle(const QString&); + void setAutoReload(); + void reload(); + + private: + KHTMLSideBar *_htmlPart; + KURL _url; + int reloadTimeout; + QString _desktopName; +}; + +#endif + diff --git a/konqueror/sidebar/web_module/webmodule_add.desktop b/konqueror/sidebar/web_module/webmodule_add.desktop new file mode 100644 index 000000000..78a9972e2 --- /dev/null +++ b/konqueror/sidebar/web_module/webmodule_add.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +Type=Link +URL= +Icon=www +Name=Web SideBar Module +Name[af]=Web kantbalk module +Name[ar]=وحدة شريط الشبكة الجانبي +Name[az]=Veb Yan Çubuq Modulu +Name[be]=Модуль cеціўнай бакавой панэлі +Name[bg]=Модул за страничния панел на браузъра +Name[bn]=ওয়েব সাইডবার মডিউল +Name[bs]=Web sidebar modul +Name[ca]=Mòdul web SideBar +Name[cs]=Webový postranní panel +Name[csb]=Moduł bòczny lëstwë WWW +Name[cy]=Modiwl Bar Ochr Gwe +Name[da]=Web-sidebjælke modul +Name[de]=Web-Navigationsbereich +Name[el]=Άρθρωμα πλευρικής μπάρας Ιστού +Name[eo]=TTT-flankzona modulo +Name[es]=Módulo de la barra lateral de web +Name[et]=Veebi külgriba moodul +Name[eu]=Web-eko alboko barraren modulua +Name[fa]=پیمانۀ میله جانبی وب +Name[fi]=Verkkosivupalkkimoduuli +Name[fr]=Module de barre de navigation sur le web +Name[fy]=Web sydbalke module +Name[ga]=Modúl Barra Taoibh Gréasáin +Name[gl]=Módulo da Barra Lateral Web +Name[he]=מודול שורת־צד מקוון +Name[hi]=वेब बाज़ूपट्टी मॉड्यूल +Name[hr]=Modul za web trake +Name[hu]=Webes oldalsáv-modul +Name[is]=Vefhliðarslá +Name[it]=Modulo barra laterale web +Name[ja]=ウェブサイドバーモジュール +Name[ka]=გვერდით Web დაფის მოდული +Name[kk]=Веб бүйір панель модулі +Name[km]=ម៉ូឌុលរបារបណ្ដាញ +Name[ko]=웹 사이드바 모듈 +Name[lt]=Šoninės žiniatinklio juostos modulis +Name[lv]=Tīmekļa sānjoslas modulis +Name[mk]=Модул - Веб-странична лента +Name[mn]=Вэб самбарын модул +Name[ms]=Modul Bar Sisi Web +Name[mt]=Barra tal-ġenb għal-web +Name[nb]=Modul for nett-sidestolpe +Name[nds]=Sietpaneel för de Nettnavigatschoon +Name[ne]=वेब छेउपट्टी मोड्युल +Name[nl]=Webzijbalkmodule +Name[nn]=Modul for nett-sidestolpe +Name[pa]=ਵੈੱਬ ਬਾਹੀ ਮੈਡੀਊਲ +Name[pl]=Moduł paska bocznego WWW +Name[pt]=Módulo da Barra Lateral Web +Name[pt_BR]=Módulo da Barra Lateral Web +Name[ro]=Modul bară laterală web +Name[ru]=Модуль боковой панели Web +Name[rw]=Igice UmurongokuRuahande cy'Urubugamakuru +Name[se]=Neahtta-bálddalasholga moduvla +Name[sk]=Modul bočného Web panelu +Name[sl]=Modul spletne stranske vrstice +Name[sr]=Модул веб бочне траке +Name[sr@Latn]=Modul veb bočne trake +Name[sv]=Webbsidoradsmodul +Name[ta]=வலை பக்கப்பட்டி பகுதி +Name[tg]=Бахши навори канораи вэб +Name[th]=โมดูลแถบด้านข้างสำหรับเว็บ +Name[tr]=Web Yan Çubuk Modülü +Name[tt]=Web YanTirä Modulı +Name[uk]=Модуль бічної панелі Тенет +Name[uz]=Veb yon paneli moduli +Name[uz@cyrillic]=Веб ён панели модули +Name[vi]=Mô đun Thanh bên Trình duyệt +Name[wa]=Module di bår di costé waibe +Name[zh_CN]=Web 侧边栏模块 +Name[zh_TW]=網頁邊列模組 +Open=false +X-KDE-KonqSidebarAddModule=konqsidebar_web +X-KDE-KonqSidebarUniversal=true diff --git a/konqueror/sidebar/web_module/websidebar.desktop b/konqueror/sidebar/web_module/websidebar.desktop new file mode 100644 index 000000000..30413e06a --- /dev/null +++ b/konqueror/sidebar/web_module/websidebar.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Type=Link +URL= +Icon=www +Name=Web SideBar Module +Name[af]=Web kantbalk module +Name[ar]=وحدة شريط الشبكة الجانبي +Name[az]=Veb Yan Çubuq Modulu +Name[be]=Модуль cеціўнай бакавой панэлі +Name[bg]=Модул за страничния панел на браузъра +Name[bn]=ওয়েব সাইডবার মডিউল +Name[bs]=Web sidebar modul +Name[ca]=Mòdul web SideBar +Name[cs]=Webový postranní panel +Name[csb]=Moduł bòczny lëstwë WWW +Name[cy]=Modiwl Bar Ochr Gwe +Name[da]=Web-sidebjælke modul +Name[de]=Web-Navigationsbereich +Name[el]=Άρθρωμα πλευρικής μπάρας Ιστού +Name[eo]=TTT-flankzona modulo +Name[es]=Módulo de la barra lateral de web +Name[et]=Veebi külgriba moodul +Name[eu]=Web-eko alboko barraren modulua +Name[fa]=پیمانۀ میله جانبی وب +Name[fi]=Verkkosivupalkkimoduuli +Name[fr]=Module de barre de navigation sur le web +Name[fy]=Web sydbalke module +Name[ga]=Modúl Barra Taoibh Gréasáin +Name[gl]=Módulo da Barra Lateral Web +Name[he]=מודול שורת־צד מקוון +Name[hi]=वेब बाज़ूपट्टी मॉड्यूल +Name[hr]=Modul za web trake +Name[hu]=Webes oldalsáv-modul +Name[is]=Vefhliðarslá +Name[it]=Modulo barra laterale web +Name[ja]=ウェブサイドバーモジュール +Name[ka]=გვერდით Web დაფის მოდული +Name[kk]=Веб бүйір панель модулі +Name[km]=ម៉ូឌុលរបារបណ្ដាញ +Name[ko]=웹 사이드바 모듈 +Name[lt]=Šoninės žiniatinklio juostos modulis +Name[lv]=Tīmekļa sānjoslas modulis +Name[mk]=Модул - Веб-странична лента +Name[mn]=Вэб самбарын модул +Name[ms]=Modul Bar Sisi Web +Name[mt]=Barra tal-ġenb għal-web +Name[nb]=Modul for nett-sidestolpe +Name[nds]=Sietpaneel för de Nettnavigatschoon +Name[ne]=वेब छेउपट्टी मोड्युल +Name[nl]=Webzijbalkmodule +Name[nn]=Modul for nett-sidestolpe +Name[pa]=ਵੈੱਬ ਬਾਹੀ ਮੈਡੀਊਲ +Name[pl]=Moduł paska bocznego WWW +Name[pt]=Módulo da Barra Lateral Web +Name[pt_BR]=Módulo da Barra Lateral Web +Name[ro]=Modul bară laterală web +Name[ru]=Модуль боковой панели Web +Name[rw]=Igice UmurongokuRuahande cy'Urubugamakuru +Name[se]=Neahtta-bálddalasholga moduvla +Name[sk]=Modul bočného Web panelu +Name[sl]=Modul spletne stranske vrstice +Name[sr]=Модул веб бочне траке +Name[sr@Latn]=Modul veb bočne trake +Name[sv]=Webbsidoradsmodul +Name[ta]=வலை பக்கப்பட்டி பகுதி +Name[tg]=Бахши навори канораи вэб +Name[th]=โมดูลแถบด้านข้างสำหรับเว็บ +Name[tr]=Web Yan Çubuk Modülü +Name[tt]=Web YanTirä Modulı +Name[uk]=Модуль бічної панелі Тенет +Name[uz]=Veb yon paneli moduli +Name[uz@cyrillic]=Веб ён панели модули +Name[vi]=Mô đun Thanh bên Trình duyệt +Name[wa]=Module di bår di costé waibe +Name[zh_CN]=Web 侧边栏模块 +Name[zh_TW]=網頁邊列模組 +Open=false +X-KDE-KonqSidebarModule=konqsidebar_web diff --git a/konqueror/sidebar/web_module/websidebar.html b/konqueror/sidebar/web_module/websidebar.html new file mode 100644 index 000000000..111356054 --- /dev/null +++ b/konqueror/sidebar/web_module/websidebar.html @@ -0,0 +1,11 @@ +<html> +<body> +<div align="center" width="80%"> +<font size="+2"> +Web SideBar Extension +</font> +<hr /> +<br /> +Select a URL with the context menu for the icon of this extension. +</body> +</html> diff --git a/konqueror/uninstall.desktop b/konqueror/uninstall.desktop new file mode 100644 index 000000000..e1e3e1732 --- /dev/null +++ b/konqueror/uninstall.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Hidden=true diff --git a/konqueror/version.h b/konqueror/version.h new file mode 100644 index 000000000..2133986cd --- /dev/null +++ b/konqueror/version.h @@ -0,0 +1,3 @@ +#ifndef _VERSION_H +#define KONQUEROR_VERSION "3.5.10" +#endif |