diff options
Diffstat (limited to 'kontact')
219 files changed, 19155 insertions, 0 deletions
diff --git a/kontact/DESIGN.dcopinteraction b/kontact/DESIGN.dcopinteraction new file mode 100644 index 000000000..f3b575987 --- /dev/null +++ b/kontact/DESIGN.dcopinteraction @@ -0,0 +1,84 @@ +How to implement DCOP communication between two applications so that +1) it works when the applications are standalone (separate processes) +2) it works when the applications are loaded as parts, embedded into kontact +3) it behaves properly when a separate process exits/crashes. + +In the part +=========== +Let's say that part 'A' wants to use the interface "Foo", via DCOP. +(where Foo is usually a generic name, e.g. Calendar, Mailer, AlarmDaemon, etc.) +The services which implement this interface are associated with the service type +"DCOP/Foo". + +One of those services is application 'B', which implements "Foo" - note that +'B' should make sure that the "Foo" DCOP interface is available both when +'B' is used as standalone process and when 'B' is only loaded as a part. +(This means that if the app doesn't use its own part, then both should implement +"Foo", like kaddressbook does. Of course it's simpler if the app uses its own part :) + +Here are some code snippets that must go into the part (A) that wants to use "Foo": + +* Constructor: + m_foo_stub = 0L; + kapp->dcopClient()->setNotifications( true ); + connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString&)), + this, SLOT( unregisteredFromDCOP( const QCString& )) ); + +* Destructor: + kapp->dcopClient()->setNotifications( false ); + delete m_foo_stub; + +[Note that setNotifications() is implemented with a refcount, this is the +correct way to do it and it won't mess up other parts] + +* bool connectToFoo() method, which uses KDCOPServiceStarter::self()->findServiceFor("DCOP/Foo"). +See test part for details (plugins/test/test_part.cpp). + +* unregisteredFromDCOP( const QCString& appId ) slot, which will be called when +the process implementing Foo exits. The method simply does: + if ( m_foo_stub && m_foo_stub->app() == appId ) + { + delete m_foo_stub; + m_foo_stub = 0; + } + +* Now you can finally use the foo dcop interface. First you need to connect +to it: + if ( !connectToFoo() ) + return; + +Then you can use m_foo_stub to call the DCOP methods. +In case of critical methods, where you want to make 100% sure that the DCOP +call was correctly done (e.g. the remote app didn't crash during the call), +you can use if ( !m_foo_stub->ok() ). + +In the kontact plugin +===================== +* Don't use dcopClient() until the part is loaded +* After loading the part, you might want to create a DCOP stub to use some +of its methods (do both in a loadPart() method, e.g.). +* Implement createDCOPInterface( const QString& serviceType ), to +load the part if the serviceType is one provided by it. + +See KAddressbookPlugin (plugins/kaddressbook/*) for a working example. + +Don't forget to +=============== +* Define the service type, using a "Type=ServiceType" .desktop file, +with "X-KDE-ServiceType=DCOP/Foo". +See e.g. kdepim/kaddressbook/dcopaddressbook.desktop + +* Add DCOP/Foo to the application's ServiceTypes list, in its .desktop file +See e.g. kdepim/kaddressbook/kaddressbook.desktop +* Make sure that X-DCOP-ServiceType and X-DCOP-ServiceName are specified too. + +Designing DCOP interfaces +========================= +Porting the kroupware signals/slots to DCOP requires some changes. +For instance any non-const reference (such as those used for returning +values to the caller) has to be changed. If there is more than one +value to be returned, you need to +* define a structure containing all the returned values +* define QDataStream << and >> operators for that structure. + +$Id$ diff --git a/kontact/HACKING b/kontact/HACKING new file mode 100644 index 000000000..b5714e390 --- /dev/null +++ b/kontact/HACKING @@ -0,0 +1,100 @@ +Coding Style +============ + +See http://korganizer.kde.org/develop/hacking.html for an HTML version. + +Formatting +---------- + +- No Tabs. +- Indent with 2 spaces. +- A line must not have more than 80 chars. +- Put Spaces between brackets and arguments of functions. +- For if, else, while and similar statements put the brackets on the same line + as the statement. +- Function and class definitions have their brackets on separate lines. + +Example: + +void MyClass::myFunction() +{ + if ( blah == fasel ) { + blubbVariable = arglValue; + } else { + blubbVariable = oerxValue; + } +} + + +Header Formatting +----------------- + +- General formatting rules apply. +- Access modifiers are indented. +- Put curly brackets of class definition on its own line. +- Double inclusion protection defines are all upper case letters and are + composed of the namespace (if available), the classname and a H suffix + separated by underscores. +- Inside a namespace there is no indentation. + +Example: + +#ifndef XKJ_MYCLASS_H +#define XKJ_MYCLASS_H + +namespace XKJ { + +class MyClass +{ + public: + MyClass(); + + private: + int mMyInt; +}; + +} + +#endif + + +API docs +-------- + +- Each public function must have a Doxygen compatible comment in the header +- Use C-style comments without additional asterisks +- Indent correctly. +- Comments should be grammatically correct, e.g. sentences start with uppercase + letters and end with a full stop. +- Be concise. + +Example: + + /** + This function makes tea. + + @param cups number of cups. + @result tea + */ + Tea makeTea( int cups ); + + +Class and File Names +-------------------- + +- Put classes in files, which have the same name as the class, but only + lower-case letters. +- Designer-generated files should have a name classname_base.ui and shoul + contain a class called ClassnameBase. +- Classes inheriting from designer-generated classes have the same name as the + generated class, but without the Base suffix. + +Class and Variable Names +------------------------ + +- For class, variable, function names seperate multiple words by upper-casing + the words precedeed by other words. +- Class names start with an upper-case letter. +- Function names start with a lower-case letter. +- Variable names start with a lower-case letter. +- Member variables of a class start with "m" followed by an upper-case letter. diff --git a/kontact/Makefile.am b/kontact/Makefile.am new file mode 100644 index 000000000..eede263a0 --- /dev/null +++ b/kontact/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = interfaces plugins src pics profiles + +DOXYGEN_REFERENCES = kdeui kparts libkcal +include $(top_srcdir)/admin/Doxyfile.am + + +messages: rc.cpp + $(EXTRACTRC) src/*.kcfg >> rc.cpp + $(XGETTEXT) rc.cpp src/*.cpp interfaces/*.cpp plugins/*/*.cpp plugins/*/*.h -o $(podir)/kontact.pot diff --git a/kontact/TODO b/kontact/TODO new file mode 100644 index 000000000..36f34905c --- /dev/null +++ b/kontact/TODO @@ -0,0 +1,29 @@ +UNTIL KDE 3.2 +============== + +- merge config of parts into a unified config dialog + * Unified Identity handling (Name, Mail address, SMTP, use KMIdentity KDEPIM wide?) + Currently this is dublicated in at least KMail, KNode and KOrganizer + * Molularize KOrganizer and KMail Settings and turn them into kcm's + * Think about extending the kcm idea and add a framework to locate kcm's for apps via KTrader +- same for unified credits +- find a solution for a setup wizard +- replace Splash class with QSplashScreen (done) +- make the "new" action a bit smarter (done) +- make korganizers part offer the normal dcop interface +- move plugins to respective apps for code sharing(?) +- Summary (what's next) view (slueppken) (done) +- Basic groupware functionality (Exchange 2k and Kolab) +- make the headerWidget look nicer (we might use KIconLoader + for larger icons) (slueppken) (done) +- make all parts use the InfoExtension (done) +- make KCMultiDialog not crash when non-existent desktop-file + is given to addModule() (done) +- support icon and buttons sidebar (done) +- enable/disable single plugins (done) + +LATER +====== + +- Support other groupware solutions +- your stuff here... diff --git a/kontact/Thoughts b/kontact/Thoughts new file mode 100644 index 000000000..e1a07c1fc --- /dev/null +++ b/kontact/Thoughts @@ -0,0 +1,375 @@ +* Note: Lines starting with a d are my comments - Daniel +* Note: Lines starting with a # are my comments - Cornelius +* Note: Lines starting with a "z" are my comments - Zack :) +* Note: Lines starting with a "s" are my comments - Simon +* Note: Lines starting with a "Don:" are my comments - Don +* Note: Lines starting with a "g" are my comments - Guenter +* Note: Lines starting with a "m" are my comments - Matthias Kretz +* Note: Lines starting with a "MiB:" are my comments - Michael +* Note: Lines starting with a "h" are my comments - Holger + +Misc: +===== + +Configuration Merge +------------------- + +d Idea: The KOffice way of life: Offer a method that adds a given wiget of a +d predefined type as page in a KDialogBase or offer a pointer to a KDialogBase +d -> requires a Kontact part or an external lib per part + +m I believe this is a more general problem. Please take a look at +m kdegraphics/kview/kpreferences{dialog,module}.{h,cpp}. I'd like to generalize +m these classes and include them into kdelibs (the same configuration merge is +m being done in Kate, Noatun, Kopete, KView and probably more). + +# The problem is even more generic. We also have to merge about boxes, tips of +# the day and maybe more. + + +Merged Foldertree View +---------------------- + +d Idea: Let the part send a description of their folders and reaction to calls +d as XML, similar to XMLGUI + +# Is a folder tree really the right tool to represent events, todos or +# contacts? + +MiB: On the one hand, Notes can be hierarchic, so a folder tree would be the +MiB: nearest solution... + +z I think so. Applications could send the root of their tree to +z Kontact so that the interface looks like + +- Mail + | \ + | - Local Folders + | \ + | Inbox + | | + | Thrash + | | + | Sent +- Notes + | \ + | Notes 1 + | | + | Notes 2 + | +- Events + \ + Event 1 + | + Event 2 + +z which is not that bad. The question would be how to render the tree +z on the Kontact side while keeping the items on the parts side ( because +z e.g. KMails hold custom pixmaps for the folders which had to be +z displayed in the Kontact tree). + +g I'm currently having 248 events. A tree is a very bad solution to visualize +g them. selecting "Events" in the tree should just only start the korganizer +g part. + +MiB: ...OTOH... yes, /me agrees with g, a folder tree becomes complex quite fast. + +Don: The folder tree makes sense for advanced users, but I think +Don: the simplicity of the current navigator widget has advantages for +Don: non power users. +Don: +Don: Actually instead of the navigator widget I think it makes sense +Don: to consider reusing the widget choosing widget in the latest +Don: version of the Qt designer, which in a sense can be +Don: considered a generalization of the navigator widget. And could +Don: make the folder tree in kmail unnecessary. +Don: +Don: I might investigate the Qt designer widget further but if someone +Don: else wants to look at a folder tree widget that's cool with me. + +# I had a look at the Qt designer widget choosing widget. I think it has a +# severe usability problem, because the buttons (or kind of tabs) which are used +# to access the widget subgroups are not always at the same place but move +# around when you click on them. Dependening on which group is shown, the button +# is at the top or at the bottom of the widget. In my opinion this solution is +# unacceptable. + +# But Daniel had a good idea how to improve that. It looks similar to the Qt +# designer widget, but it opens the current group always at the top of the +# widget and only highlights the current group in the list at the bottom, but +# doesn't move it. This seems to also be the way Outlook does it. + +Don: Guenter, agree. +Don: Wouldn't the idea to be to show calendars in the tree or +Don: navigator widget, rather than individual events? + +# Yes, that makes sense. Calendars are much more similar to mail folders than +# single events. You wouldn't integrate individual mails in the folder tree, +# would you? + +d That raises an interesting point: The KNotes plugin would not need an own +d canvas in the WidgetStack then. It's sufficient to have the notes in the +d folder view, an RMB menu on them and a "New Note" action. +d So the new design must be able to catch that case (the current one does not). + +# I think notes are on the same level as mails or events. They should be listed +# in the view. KNotes would probably just create a single entry in the folder +# tree. + + +KNotes integration +------------------ + +MiB: Which reminds me of my own concern about the 'how' of integrating KNotes: +MiB: * the current solution is to start KNotes extern, it is not embedded in Kontact +MiB: at all. Thus opening a note that is on another desktop either leaves the Kontact +MiB: window or moves the note. Either not perfect. Also, Kontact is likely to cover +MiB: notes that reside on the desktop, easy working is impossible. Which is the reason +MiB: I don't like the current approach too much. +MiB: * but there's always hope---my idea would be to show the notes in Kontact itself. +MiB: Now I tend to say it's a bit intrusive to not allow starting KNotes and +MiB: Kontact/KNotes at the same time which raises the following issues: +MiB: - if KNotes and Kontact are running at the same time, changes to the notes have +MiB: to be synchronized (not much of a problem). Changes to be synced are the +MiB: text/contents itself, the text color/style..., the note color. Not sure about +MiB: the note size. Not to be synced is the position. +MiB: - so the position in Kontact has to be saved individually and independently +MiB: of the real desktop position (realized by attaching two display config +MiB: files, works in make_it_cool branch mostly). Kontact's size is generally +MiB: smaller than the desktop. +MiB: - normally notes are on a specific desktop, now they have to be displayed on one +MiB: area---how to do this best? + +MiB: what does M$ do? How do they manage the notes in their PIM app? (I don't know +MiB: it, never seen that thing) + + +Toolbar Items +------------- + +d The KParts Technology only provides actions for the current part. It might be +d desireable to have common actions that are always available. + +Don: I agree that it is desireable to have common actions always +Don: available (and parts too like the todo list) +Don: +Don: But are you sure Kparts is limited in this way? KOrganizer can load +Don: multiple plugins simultaneously. And all of these plugins are kparts +Don: (eg. birthday import), and kactions for all loaded plugins are +Don: created and made available simultaneously. +Don: +Don: Yeah, I'm quite positive you can load multiple parts simultaneously. + +# Certainly. Actions like "New Mail", "New Contact", "New Event" should be +# available independently of a selected part. + +Don: This is a very important issue, I think we need a library with three +Don: methods: +Don: KAddressBookIface loadKAddressBook() +Don: KMailIface loadKMail() +Don: KOrganizerIface loadKOrganizer() +MiB: And don't forget KNotesIface loadKNotes() :-) + +h: That doesn't sound extendable ;) +h: So if I would like to add a 'New ShortMessage' part we would have to extend +h: that library... better use KTrader and some sort of a common framework +h: and Mib's comments shows that problem! + +d: That's what KDCOPServiceStarter is for :) + +Don: Now if kontact is running then loadX will load the X part in kontact +Don: (if it is not already loaded) and return a dcop iface for that +Don: part. +Don: +Don: If kontact is not running but is the users preferred application +Don: then loadX will start kontact and then do the above. +Don: +Don: If kontact is not running and is not the users preferred application +Don: then a standalone version of X should be started, and an iface for +Don: that standalone app returned. +Don: +Don: I think this library should be in libkdepim ad all the kdepim apps +Don: should be moved into kdepim, so their iface files all be in one +Don: package. Or alternatively a new kdeinterfaces package be created +Don: and used as a general repository for interface files. +Don: +Don: Another important issue is invokeMailer and the fact that currently +Don: KDE just runs kmail with command line arguments by default. That has +Don: to be made smarter. +Don: +Don: I guess when kmail is run with command line arguments it could +Don: actually use loadKMail() and then use the resulting iface. +Don: +Don: And the same for all other loadX apps. + + +Status Bar +---------- + +d We need a more sophisticated handling (progressbar, etc) + +Don: Definitely. + +# We now have kdelibs/kparts/statusbarextension. This is intended to solve these +# problems, right? + +d: Right. Simply add it as childobject in your part and use it's API. Works even +d: for other KPart hosts than Kontact + + +Kontact plugin unification +------------------------- + +# Currently all Kontact plugins look quite similar. It would be nice, if we +# could provide infratructure to reduce duplicated code as far as possible. + +d I thouht of a KontactPart, similar to a KOPart, if that makes sense. I don't think +d a normal KPart is sufficient for us. + +Don: I've spent quite a bit of time in all pim *_part files and IIRC +Don: the amount of duplicated code, is pretty much negligible. +Don: +Don: But a KontactPart could make sense for when the parts want to communicate with +Don: the container. Eg. if the parts want to add folders to the container +Don: apps folder tree (or navigator) +Don: +Don: And maybe for communicating with the status bar. + + +Communication/Interaction: +========================== + +d Invoking parts when they are needed for the first time takes too long, +d starting all takes too long on startup +d Idea: Mark complex parts as basic parts that get loaded anyway + +# parts could be loaded in the background based on usage patterns. Kontact could +# remember which parts were used at the last session and load them in the +# background after loading the initial part to be shown at startup. + +z This idea seems to be similar to Microsoft's +z hide-unused-item-in-the-menu strategy. But it probably mess up +z kaddressbook integration. Although not used during every session +z this part is needed and should be always loaded. This strategy +z would be great for could-to-come parts, like a summary part. +z Background loading of parts is OK. The idea is simple : load the +z last used part on startup. Make sure its loading finishes and then +z load the rest once the user can already interact with the last used +z loaded part. + +g why do we always need the addressbook? Is libkabc not sufficient? + +Don: I guess my machine is too fast, starting parts is pretty quick here :-) + +d DCOP is too slow, internal communication should be handled via a dedicated +d interface, communication with external applications (i.e. knotes) should be +d done via wrapper parts that communicate with their respective IPC method to +d their application using the native protocol (DCOP, Corba, etc). + +# Are you sure that DCOP is too slow for in-process communications? I thought it +# would handle this special case efficiently. + +s It is only efficient in the sense that it won't do a roundtrip to the server but +s dispatch locally. What remains is the datastream marshalling. Not necessarily +s ueberfast. But I think the point is a different one: It is simply not as intuitive +s to use as C++. Yes, DCOPRef already helps a lot for simple calls, but talking to +s remote components still requires one to do error checking after each method call. +s in addition the stub objects one deals with (AddressBookIface_stub for example) +s are no real references. To the programmer they look like a reference to a +s remote addressbook component, but it really isn't. there is no state involved. +s like if between two method calls on the stub the addressbook process gets restarted, +s the state is lost and the programmer on the client side has no way to find out +s about that. you'll end up with really complex code on the caller side to handle things +s like that. + +d Yes, but of course one should always prefer in-process IPC if possible. DCOP +d currently _works_ for Kontact, but that's all about it. It isn't exactly elegant. +d The only advantange of the current approach is that we can allow the user to +d run one of the parts standalone. I am not really sure we want that. I used to find +d it desireable, but I am not sure anymore. + +MiB: But that's the whole idea behind Kontact---to be able to integrate apps +MiB: _and_ to have standalone versions. Just think about KNotes... impossible +MiB: to have it limited to only Kontact! + +Don: I love being able to run the apps inside or outside of the +Don: container, it's just really cool being able to choose I think it's a +Don: great feature and users will really love having the +Don: choice. Especially when they are migrating. + +MiB: Definitely. + +Don: I think if we use the loadX methods defined above then we can still +Don: support this. I'm PRO DCOP. And this way we don't have to special +Don: case of the code depending on whether the application is running in +Don: a container app or not. +Don: +Don: I find difficult to imagine a function that DCOP is not fast enough +Don: to support. It supports all our current PIM IPC needs fine. + +MiB: yes, not too much against DCOP. But for KNotes I thought about turning +MiB: a note into a plugin that can be loaded by Kontact and KNotes independently. +MiB: like this, there's no DCOP necessary anymore and makes it much more flexible. +MiB: e.g. usage of different display configs, a note embedded somewhere and having +MiB: a parent or standalone on the desktop. + +# Communication with external applications is something which doesn't fit too +# well with the 'integrated' approach of Kontact. Is this really necessary? + +d We won't get around it, think knotes, maybe sync tools, think abstact 3rd party +d projects (not sure the latter is really that important, but we should consider it. +d it barely plays a role anyway). + +MiB: hm. true. But not too important, IMHO. Just add a Kontact-DCOP interface :-) + +h: Pretty much to talk about... +h: 1. the speed of DCOP is not that important. I worry more about the integration +h: of all parts. So how would I cross reference an 'Event' with a 3rd party +h: Kaplan Part? A common base class for all PIM records comes into my mind - again - +h: Now with normal C++ you can pass a pointer through the framework +h: Doing it with DCOP we need to marshall and demarshall it. This part can get really +h: ugly if we want more tight integration of all KaplanParts. We could add +h: a pure virtual method to marshall to a QDataStream. So now marshalling is done. +h: For demarshalling we need to get the type of the QDataStream content and then we need +h: to ask someone - a factory - to get a object for the type and then call another pure +h: virtual..... +h: The question is if this is really necessary +h: 2. stand a lone apps +h: The 'stand a lone' app can always run in the same address space but be a top level widget +h: itself. WIth some DCOP magic clicking on the KMAIL icon code make Kaplan detach the part... +h: 3. Integration! +h: The goal of Kaplan should not be to merge some XML files an give a common Toolbar for +h: X applications in one shell. I want true integration. Yes KMAIL can use KABC to show +h: all emails for one contact but a generic way to do such things would be more than nice. +h: It would be nice if I could relate the PIM objects in a common way. So I create an Event and +h: relate some todos to it. So for KDE4 I want a common base class for all PIM classes including mail +h: see Opies OPimRecord for a bit too huge base class + +Security +-------- + +d If we use the kparts (ktrader) approach to find a parts by looking +d for an application with the correct mime type this might raise security +d problems. (Martin's concern) + +# Looking up Kontact parts isn't based on mime types but on services of type +# "Kontact/Plugin". This is just as save as starting a program statically linking +# its parts. I really don't see any security concerns here. + +d Ok, if we limit stuff to Kontact/Plugin and Kontact/Part that might be safe enough +d indeed. I (and Martin, who raise this concern initially) was just afraid of +d allowing "any" part. + +h: hmm If somebody can install a Service into the global kde dir or the user kde home +h: there is something else broken IMHO + + +Summary View +------------ +h: How would one best integrate a summary view into kontact? +h: a) add a virtual QWidget *summary(const QDateTime&, QWidget* parent ); +h: to get a summary widget for a day? +h: b) use some sort of XML to UI to represent the summary informations +h: c) have a stand a lone part which opens the PIM data seperately? ( How +h: to synchronize access? ) + diff --git a/kontact/interfaces/Makefile.am b/kontact/interfaces/Makefile.am new file mode 100644 index 000000000..94a15dda3 --- /dev/null +++ b/kontact/interfaces/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir) $(all_includes) + +lib_LTLIBRARIES = libkpinterfaces.la + +libkpinterfaces_la_SOURCES = core.cpp plugin.cpp summary.cpp uniqueapphandler.cpp +libkpinterfaces_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 1:0:0 +libkpinterfaces_la_LIBADD = ../../libkdepim/libkdepim.la $(LIB_KPARTS) + +kpincludedir = $(includedir)/kontact +kpinclude_HEADERS = core.h plugin.h summary.h + +METASOURCES = AUTO + +servicetypedir = $(kde_servicetypesdir) +servicetype_DATA = kontactplugin.desktop diff --git a/kontact/interfaces/core.cpp b/kontact/interfaces/core.cpp new file mode 100644 index 000000000..19ed8bade --- /dev/null +++ b/kontact/interfaces/core.cpp @@ -0,0 +1,129 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org> + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "core.h" + +#include <kparts/part.h> +#include <kparts/componentfactory.h> +#include <kdebug.h> +#include <qtimer.h> +#include <klocale.h> + +using namespace Kontact; + +class Core::Private +{ +public: + QString lastErrorMessage; +}; + +Core::Core( QWidget *parent, const char *name ) + : KParts::MainWindow( parent, name ) +{ + d = new Private; + QTimer* timer = new QTimer( this ); + mLastDate = QDate::currentDate(); + connect(timer, SIGNAL( timeout() ), SLOT( checkNewDay() ) ); + timer->start( 1000*60 ); +} + +Core::~Core() +{ + delete d; +} + +KParts::ReadOnlyPart *Core::createPart( const char *libname ) +{ + kdDebug(5601) << "Core::createPart(): " << libname << endl; + + QMap<QCString,KParts::ReadOnlyPart *>::ConstIterator it; + it = mParts.find( libname ); + if ( it != mParts.end() ) return it.data(); + + kdDebug(5601) << "Creating new KPart" << endl; + + int error = 0; + KParts::ReadOnlyPart *part = + KParts::ComponentFactory:: + createPartInstanceFromLibrary<KParts::ReadOnlyPart> + ( libname, this, 0, this, "kontact", QStringList(), &error ); + + KParts::ReadOnlyPart *pimPart = dynamic_cast<KParts::ReadOnlyPart*>( part ); + if ( pimPart ) { + mParts.insert( libname, pimPart ); + QObject::connect( pimPart, SIGNAL( destroyed( QObject * ) ), + SLOT( slotPartDestroyed( QObject * ) ) ); + } else { + // TODO move to KParts::ComponentFactory + switch( error ) { + case KParts::ComponentFactory::ErrNoServiceFound: + d->lastErrorMessage = i18n( "No service found" ); + break; + case KParts::ComponentFactory::ErrServiceProvidesNoLibrary: + d->lastErrorMessage = i18n( "Program error: the .desktop file for the service does not have a Library key." ); + break; + case KParts::ComponentFactory::ErrNoLibrary: + d->lastErrorMessage = KLibLoader::self()->lastErrorMessage(); + break; + case KParts::ComponentFactory::ErrNoFactory: + d->lastErrorMessage = i18n( "Program error: the library %1 does not provide a factory." ).arg( libname ); + break; + case KParts::ComponentFactory::ErrNoComponent: + d->lastErrorMessage = i18n( "Program error: the library %1 does not support creating components of the specified type" ).arg( libname ); + break; + } + kdWarning(5601) << d->lastErrorMessage << endl; + } + + return pimPart; +} + +void Core::slotPartDestroyed( QObject * obj ) +{ + // the part was deleted, we need to remove it from the part map to not return + // a dangling pointer in createPart + QMap<QCString, KParts::ReadOnlyPart*>::Iterator end = mParts.end(); + QMap<QCString, KParts::ReadOnlyPart*>::Iterator it = mParts.begin(); + for ( ; it != end; ++it ) { + if ( it.data() == obj ) { + mParts.remove( it ); + return; + } + } +} + +void Core::checkNewDay() +{ + if ( mLastDate != QDate::currentDate() ) + emit dayChanged( QDate::currentDate() ); + + mLastDate = QDate::currentDate(); +} + +QString Core::lastErrorMessage() const +{ + return d->lastErrorMessage; +} + +#include "core.moc" +// vim: sw=2 sts=2 et tw=80 diff --git a/kontact/interfaces/core.h b/kontact/interfaces/core.h new file mode 100644 index 000000000..2ebe088f9 --- /dev/null +++ b/kontact/interfaces/core.h @@ -0,0 +1,102 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ +#ifndef KONTACT_CORE_H +#define KONTACT_CORE_H + +#include <qdatetime.h> +#include <kdepimmacros.h> +#include <kparts/mainwindow.h> +#include <kparts/part.h> + +class KAction; + +namespace Kontact +{ + +class Plugin; + +/** + This class provides the interface to the Kontact core for the plugins. +*/ +class KDE_EXPORT Core : public KParts::MainWindow +{ + Q_OBJECT + public: + virtual ~Core(); + + /** + Selects the given plugin @param plugin and raises the associated + part. + */ + virtual void selectPlugin( Kontact::Plugin *plugin ) = 0; + + /** + This is an overloaded member function. It behaves essentially like the + above function. + */ + virtual void selectPlugin( const QString &plugin ) = 0; + + /** + Returns the pointer list of available plugins. + */ + virtual QValueList<Kontact::Plugin*> pluginList() const = 0; + + /** + @internal (for Plugin) + */ + KParts::ReadOnlyPart *createPart( const char *libname ); + + /** + @internal (for Plugin) + Tell kontact that a part was loaded + */ + virtual void partLoaded( Plugin* plugin, KParts::ReadOnlyPart * part ) = 0; + + signals: + /** + Emitted when a new day starts + */ + void dayChanged( const QDate& ); + + protected: + Core( QWidget *parentWidget = 0, const char *name = 0 ); + + QString lastErrorMessage() const; + + private slots: + void slotPartDestroyed( QObject * ); + void checkNewDay(); + + private: + QMap<QCString,KParts::ReadOnlyPart *> mParts; + QDate mLastDate; + + class Private; + Private *d; +}; + +} + +#endif + +// vim: sw=2 sts=2 et tw=80 diff --git a/kontact/interfaces/kontactplugin.desktop b/kontact/interfaces/kontactplugin.desktop new file mode 100644 index 000000000..28803bc6d --- /dev/null +++ b/kontact/interfaces/kontactplugin.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=Kontact/Plugin +Name=Kontact Plugin +Name[af]=Kontact inprop module +Name[ar]=قابس Kontact +Name[be]=Дапаўненне Кантакту +Name[bg]=Приставка на Kontact +Name[br]=Lugent Kontact +Name[bs]=Dodatak za Kontact +Name[ca]=Endollable Kontact +Name[cs]=Modul aplikace Kontact +Name[cy]=Ategyn Kontact +Name[da]=Kontact-plugin +Name[de]=Kontact-Modul +Name[el]=Πρόσθετο Kontact +Name[es]=Plugin Kontact +Name[et]=Kontacti plugin +Name[eu]=Kontact plugin-a +Name[fa]=وصلۀ Kontact +Name[fi]=Kontact-liitännäinen +Name[fr]=Module Kontact +Name[ga]=Breiseán Kontact +Name[gl]=Extensión de Kontact +Name[he]=תוסף Kontact +Name[hi]=कॉन्टेक्ट प्लगइन +Name[hu]=Kontact-bővítőmodul +Name[is]=Kontact íforrit +Name[it]=Plugin Kontact +Name[ja]=Kontact プラグイン +Name[ka]=Kontact მოდული +Name[kk]=Kontact модулі +Name[km]=កម្មវិធីជំនួយ Kontact +Name[lt]=Kontact priedas +Name[mk]=Приклучок за Контакт +Name[ms]=Plugin Kontact +Name[nb]=Kontact-programtillegg +Name[nds]=Kontact-Moduul +Name[ne]=सम्पर्क प्लगइन +Name[nn]=Kontact-programtillegg +Name[pl]=Wtyczka Kontakt +Name[pt]='Plugin' do Kontact +Name[pt_BR]=Plug-in do Kontact +Name[ro]=Modul Kontact +Name[ru]=Модуль Kontact +Name[se]=Kontact-lassemoduvla +Name[sl]=Vstavek za Kontact +Name[sr]=Прикључак Kontact-а +Name[sr@Latn]=Priključak Kontact-a +Name[sv]=Kontact-insticksprogram +Name[ta]=சொருகுப்பொருளை தொடர்புக்கொள் +Name[tg]=Модули Kontact +Name[tr]=Kontact Eklentisi +Name[uk]=Втулок Kontact +Name[uz]=Kontact uchun plagin +Name[uz@cyrillic]=Kontact учун плагин +Name[zh_CN]=Kontact 插件 +Name[zh_TW]=Kontack 外掛程式 + +[PropertyDef::X-KDE-KontactPluginVersion] +Type=int +[PropertyDef::X-KDE-KontactPartLibraryName] +Type=QString +[PropertyDef::X-KDE-KontactPartExecutableName] +Type=QString +[PropertyDef::X-KDE-KontactPartLoadOnStart] +Type=bool +[PropertyDef::X-KDE-KontactPluginHasSummary] +Type=bool +[PropertyDef::X-KDE-KontactPluginHasPart] +Type=bool diff --git a/kontact/interfaces/plugin.cpp b/kontact/interfaces/plugin.cpp new file mode 100644 index 000000000..33662015c --- /dev/null +++ b/kontact/interfaces/plugin.cpp @@ -0,0 +1,259 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qobjectlist.h> + +#include <dcopclient.h> +#include <kaboutdata.h> +#include <kglobal.h> +#include <kparts/componentfactory.h> +#include <kdebug.h> +#include <kinstance.h> +#include <krun.h> + +#include "core.h" +#include "plugin.h" + +using namespace Kontact; + +class Plugin::Private +{ + public: + Kontact::Core *core; + DCOPClient *dcopClient; + QPtrList<KAction> *newActions; + QPtrList<KAction> *syncActions; + QString identifier; + QString title; + QString icon; + QString executableName; + QCString partLibraryName; + bool hasPart; + KParts::ReadOnlyPart *part; + bool disabled; +}; + + +Plugin::Plugin( Kontact::Core *core, QObject *parent, const char *name ) + : KXMLGUIClient( core ), QObject( parent, name ), d( new Private ) +{ + core->factory()->addClient( this ); + KGlobal::locale()->insertCatalogue(name); + + d->core = core; + d->dcopClient = 0; + d->newActions = new QPtrList<KAction>; + d->syncActions = new QPtrList<KAction>; + d->hasPart = true; + d->part = 0; + d->disabled = false; +} + + +Plugin::~Plugin() +{ + delete d->part; + delete d->dcopClient; + delete d; +} + +void Plugin::setIdentifier( const QString &identifier ) +{ + d->identifier = identifier; +} + +QString Plugin::identifier() const +{ + return d->identifier; +} + +void Plugin::setTitle( const QString &title ) +{ + d->title = title; +} + +QString Plugin::title() const +{ + return d->title; +} + +void Plugin::setIcon( const QString &icon ) +{ + d->icon = icon; +} + +QString Plugin::icon() const +{ + return d->icon; +} + +void Plugin::setExecutableName( const QString& bin ) +{ + d->executableName = bin; +} + +QString Plugin::executableName() const +{ + return d->executableName; +} + +void Plugin::setPartLibraryName( const QCString &libName ) +{ + d->partLibraryName = libName; +} + +KParts::ReadOnlyPart *Plugin::loadPart() +{ + return core()->createPart( d->partLibraryName ); +} + +const KAboutData *Plugin::aboutData() +{ + kdDebug(5601) << "Plugin::aboutData(): libname: " << d->partLibraryName << endl; + + const KInstance *instance = + KParts::Factory::partInstanceFromLibrary( d->partLibraryName ); + + if ( instance ) { + return instance->aboutData(); + } else { + kdError() << "Plugin::aboutData(): Can't load instance for " + << title() << endl; + return 0; + } +} + +KParts::ReadOnlyPart *Plugin::part() +{ + if ( !d->part ) { + d->part = createPart(); + if ( d->part ) { + connect( d->part, SIGNAL( destroyed() ), SLOT( partDestroyed() ) ); + core()->partLoaded( this, d->part ); + } + } + return d->part; +} + +QString Plugin::tipFile() const +{ + return QString::null; +} + + +DCOPClient* Plugin::dcopClient() const +{ + if ( !d->dcopClient ) { + d->dcopClient = new DCOPClient(); + // ### Note: maybe we could use executableName().latin1() instead here. + // But this requires that dcopClient is NOT called by the constructor, + // and is called by some new virtual void init() later on. + d->dcopClient->registerAs( name(), false ); + } + + return d->dcopClient; +} + +void Plugin::insertNewAction( KAction *action ) +{ + d->newActions->append( action ); +} + +void Plugin::insertSyncAction( KAction *action ) +{ + d->syncActions->append( action ); +} + +QPtrList<KAction> *Plugin::newActions() const +{ + return d->newActions; +} + +QPtrList<KAction> *Plugin::syncActions() const +{ + return d->syncActions; +} + +Kontact::Core *Plugin::core() const +{ + return d->core; +} + +void Plugin::select() +{ +} + +void Plugin::configUpdated() +{ +} + +void Plugin::partDestroyed() +{ + d->part = 0; +} + +void Plugin::slotConfigUpdated() +{ + configUpdated(); +} + +void Plugin::bringToForeground() +{ + if (!d->executableName.isEmpty()) + KRun::runCommand(d->executableName); +} + +bool Kontact::Plugin::showInSideBar() const +{ + return d->hasPart; +} + +void Kontact::Plugin::setShowInSideBar( bool hasPart ) +{ + d->hasPart = hasPart; +} + +void Kontact::Plugin::setDisabled( bool disabled ) +{ + d->disabled = disabled; +} + +bool Kontact::Plugin::disabled() const +{ + return d->disabled; +} + +void Kontact::Plugin::loadProfile( const QString& ) +{ +} + +void Kontact::Plugin::saveToProfile( const QString& ) const +{ +} + +void Plugin::virtual_hook( int, void* ) { + //BASE::virtual_hook( id, data ); +} + +#include "plugin.moc" + +// vim: sw=2 et sts=2 tw=80 diff --git a/kontact/interfaces/plugin.h b/kontact/interfaces/plugin.h new file mode 100644 index 000000000..c80227984 --- /dev/null +++ b/kontact/interfaces/plugin.h @@ -0,0 +1,291 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org> + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KONTACT_PLUGIN_H +#define KONTACT_PLUGIN_H + +#include <qobject.h> +#include <kxmlguiclient.h> +#include <kdepimmacros.h> +#include <qptrlist.h> + +class QStringList; +class DCOPClient; +class DCOPObject; +class KAboutData; +class KAction; +class KConfig; +class QWidget; +namespace KParts { class ReadOnlyPart; } + +/** + Increase this version number whenever you make a change + in the API. + */ +#define KONTACT_PLUGIN_VERSION 6 + +namespace Kontact +{ + +class Core; +class Summary; + +/** + Base class for all Plugins in Kontact. Inherit from it + to get a plugin. It can insert an icon into the sidepane, + add widgets to the widgetstack and add menu items via XMLGUI. + */ +class KDE_EXPORT Plugin : public QObject, virtual public KXMLGUIClient +{ + Q_OBJECT + + public: + /** + Creates a new Plugin, note that name parameter name is required if + you want your plugin to do dcop via it's own instance of + DCOPClient by calling dcopClient. + @note name MUST be the name of the application that + provides the part! This is the name used for DCOP registration. + It's ok to have several plugins using the same application name. + */ + Plugin( Core *core, QObject *parent, const char *name ); + + ~Plugin(); + + /** + Sets the identifier. + */ + void setIdentifier( const QString &identifier ); + + /** + Returns the identifier. It is used as argument for several + methods of Kontacts core. + */ + QString identifier() const; + + /** + Sets the localized title. + */ + void setTitle( const QString &title ); + + /** + Returns the localized title. + */ + QString title() const; + + /** + Sets the icon name. + */ + void setIcon( const QString &icon ); + + /** + Returns the icon name. + */ + QString icon() const; + + /** + Sets the name of executable (if existant). + */ + void setExecutableName( const QString &bin ); + + /** + Returns the name of the binary (if existant). + */ + QString executableName() const; + + /** + Set name of library which contains the KPart used by this plugin. + */ + void setPartLibraryName( const QCString & ); + + /** + Create the DCOP interface for the given @p serviceType, if this + plugin provides it. Return false otherwise. + */ + virtual bool createDCOPInterface( const QString& /*serviceType*/ ) { return false; } + + /** + Reimplement this method and return wether a standalone application is still running + This is only required if your part is also available as standalone application. + */ + virtual bool isRunningStandalone() { return false; } + + /** + Reimplement this method if your application needs a different approach to be brought + in the foreground. The default behaviour is calling the binary. + This is only required if your part is also available as standalone application. + */ + virtual void bringToForeground(); + + /** + Reimplement this method if you want to add your credits to the Kontact + about dialog. + */ + virtual const KAboutData *aboutData(); + + /** + You can use this method if you need to access the current part. You can be + sure that you always get the same pointer as long as the part has not been + deleted. + */ + KParts::ReadOnlyPart *part(); + + /** + Reimplement this method and return the a path relative to "data" to the tips file. + */ + virtual QString tipFile() const; + + /** + This function is called when the plugin is selected by the user before the + widget of the KPart belonging to the plugin is raised. + */ + virtual void select(); + + /** + This function is called whenever the config dialog has been closed + successfully. + */ + virtual void configUpdated(); + + /** + Reimplement this method if you want to add a widget for your application + to Kontact's summary page. + */ + virtual Summary *createSummaryWidget( QWidget * /*parent*/ ) { return 0; } + + /** + Returns wether the plugin provides a part that should be shown in the sidebar. + */ + virtual bool showInSideBar() const; + + /** + Set if the plugin provides a part that should be shown in the sidebar. + */ + void setShowInSideBar( bool hasPart ); + + /** + Reimplement this method if you want to add checks before closing down the main kontact + window. Return true if it's OK to close the window. If any loaded plugin returns false + from this method, then the main kontact window will not close. + */ + virtual bool queryClose() const { return true; } + + /** + Retrieve the current DCOP Client for the plugin. + + The clients name is taken from the name argument in the constructor. + @note: The DCOPClient object will only be created when this method is + called for the first time. Make sure that the part has been loaded + before calling this method, if it's the one that contains the DCOP + interface that other parts might use. + */ + DCOPClient *dcopClient() const; + + /** + Return the weight of the plugin. The higher the weight the lower it will + be displayed in the sidebar. The default implementation returns 0. + */ + virtual int weight() const { return 0; } + + /** + Insert "New" action. + */ + void insertNewAction( KAction *action ); + + /** + Insert "Sync" action. + */ + void insertSyncAction( KAction *action ); + + /** + FIXME: write API doc for Kontact::Plugin::newActions(). + */ + QPtrList<KAction>* newActions() const; + + /** + FIXME: write API doc for Kontact::Plugin::syncActions(). + */ + QPtrList<KAction>* syncActions() const; + + /** + Returns a list of action name which shall be hidden in the main toolbar. + */ + virtual QStringList invisibleToolbarActions() const { return QStringList(); } + + /** + Return, if the plugin can handle the drag object of the given mime type. + */ + virtual bool canDecodeDrag( QMimeSource * ) { return false; } + + /** + Process drop event. + */ + virtual void processDropEvent( QDropEvent * ) {} + + virtual void loadProfile( const QString& directoryPath ); + + virtual void saveToProfile( const QString& directoryPath ) const; + + /** + * Session management: read properties + */ + virtual void readProperties( KConfig * ) {} + + /** + * Session management: save properties + */ + virtual void saveProperties( KConfig * ) {} + + Core *core() const; + + bool disabled() const; + void setDisabled( bool v ); + + public slots: + /** + internal usage + */ + void slotConfigUpdated(); + + protected: + /** + Reimplement and return the part here. Reimplementing createPart() is + mandatory! + */ + virtual KParts::ReadOnlyPart *createPart() = 0; + + KParts::ReadOnlyPart *loadPart(); + + virtual void virtual_hook( int id, void* data ); + + private slots: + void partDestroyed(); + + private: + class Private; + Private *d; +}; + +} + +#endif diff --git a/kontact/interfaces/summary.cpp b/kontact/interfaces/summary.cpp new file mode 100644 index 000000000..f4e38771d --- /dev/null +++ b/kontact/interfaces/summary.cpp @@ -0,0 +1,116 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "summary.h" + +#include <qimage.h> +#include <qdragobject.h> +#include <qhbox.h> +#include <qfont.h> +#include <qlabel.h> +#include <qpainter.h> + +#include <kiconloader.h> +#include <kdialog.h> + +using namespace Kontact; + +Summary::Summary( QWidget *parent, const char *name ) + : QWidget( parent, name ) +{ + setAcceptDrops( true ); +} + +Summary::~Summary() +{ +} + +QWidget* Summary::createHeader(QWidget *parent, const QPixmap& icon, const QString& heading) +{ + QHBox* hbox = new QHBox( parent ); + hbox->setMargin( 2 ); + + QFont boldFont; + boldFont.setBold( true ); + boldFont.setPointSize( boldFont.pointSize() + 2 ); + + QLabel *label = new QLabel( hbox ); + label->setPixmap( icon ); + label->setFixedSize( label->sizeHint() ); + label->setPaletteBackgroundColor( colorGroup().mid() ); + label->setAcceptDrops( true ); + + label = new QLabel( heading, hbox ); + label->setAlignment( AlignLeft|AlignVCenter ); + label->setIndent( KDialog::spacingHint() ); + label->setFont( boldFont ); + label->setPaletteForegroundColor( colorGroup().light() ); + label->setPaletteBackgroundColor( colorGroup().mid() ); + + hbox->setPaletteBackgroundColor( colorGroup().mid() ); + + hbox->setMaximumHeight( hbox->minimumSizeHint().height() ); + + return hbox; +} + +void Summary::mousePressEvent( QMouseEvent *event ) +{ + mDragStartPoint = event->pos(); + + QWidget::mousePressEvent( event ); +} + +void Summary::mouseMoveEvent( QMouseEvent *event ) +{ + if ( (event->state() & LeftButton) && + (event->pos() - mDragStartPoint).manhattanLength() > 4 ) { + + QDragObject *drag = new QTextDrag( "", this, "SummaryWidgetDrag" ); + + QPixmap pm = QPixmap::grabWidget( this ); + if ( pm.width() > 300 ) + pm = pm.convertToImage().smoothScale( 300, 300, QImage::ScaleMin ); + + QPainter painter; + painter.begin( &pm ); + painter.setPen( Qt::gray ); + painter.drawRect( 0, 0, pm.width(), pm.height() ); + painter.end(); + drag->setPixmap( pm ); + drag->dragMove(); + } else + QWidget::mouseMoveEvent( event ); +} + +void Summary::dragEnterEvent( QDragEnterEvent *event ) +{ + event->accept( QTextDrag::canDecode( event ) ); +} + +void Summary::dropEvent( QDropEvent *event ) +{ + int alignment = (event->pos().y() < (height() / 2) ? Qt::AlignTop : Qt::AlignBottom); + emit summaryWidgetDropped( this, event->source(), alignment ); +} + +#include "summary.moc" diff --git a/kontact/interfaces/summary.h b/kontact/interfaces/summary.h new file mode 100644 index 000000000..8ef96ef2c --- /dev/null +++ b/kontact/interfaces/summary.h @@ -0,0 +1,94 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef KONTACT_SUMMARY_H +#define KONTACT_SUMMARY_H + +#include <qwidget.h> +#include <qpixmap.h> +#include <kdepimmacros.h> + +class KStatusBar; + +namespace Kontact +{ + +/** + Summary widget for display in the Summary View plugin. + */ +class KDE_EXPORT Summary : public QWidget +{ + Q_OBJECT + + public: + Summary( QWidget *parent, const char *name = 0 ); + + virtual ~Summary(); + + /** + Return logical height of summary widget. This is used to calculate how + much vertical space relative to other summary widgets this widget will use + in the summary view. + */ + virtual int summaryHeight() const { return 1; } + + /** + Creates a heading for a typical summary view with an icon and a heading. + */ + QWidget *createHeader( QWidget* parent, const QPixmap &icon, + const QString& heading ); + + /** + Return list of strings identifying configuration modules for this summary + part. The string has to be suitable for being passed to + KCMultiDialog::addModule(). + */ + virtual QStringList configModules() const { return QStringList(); } + + public slots: + virtual void configChanged() {} + + /** + This is called if the displayed information should be updated. + @param force true if the update was requested by the user + */ + virtual void updateSummary( bool force = false ) { Q_UNUSED( force ); } + + signals: + void message( const QString &message ); + void summaryWidgetDropped( QWidget *target, QWidget *widget, int alignment ); + + protected: + virtual void mousePressEvent( QMouseEvent* ); + virtual void mouseMoveEvent( QMouseEvent* ); + virtual void dragEnterEvent( QDragEnterEvent* ); + virtual void dropEvent( QDropEvent* ); + + private: + KStatusBar *mStatusBar; + QPoint mDragStartPoint; + + class Private; + Private *d; +}; + +} + +#endif diff --git a/kontact/interfaces/uniqueapphandler.cpp b/kontact/interfaces/uniqueapphandler.cpp new file mode 100644 index 000000000..de77df7d5 --- /dev/null +++ b/kontact/interfaces/uniqueapphandler.cpp @@ -0,0 +1,201 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 David Faure <faure@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "uniqueapphandler.h" +#include <kstartupinfo.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include "core.h" +#include <kwin.h> +#include <dcopclient.h> +#include <kdebug.h> +#include <klocale.h> +#include <kuniqueapplication.h> + +/* + Test plan for the various cases of interaction between standalone apps and kontact: + + 1) start kontact, select "Mail". + 1a) type "korganizer" -> it switches to korganizer + 1b) type "kmail" -> it switches to kmail + 1c) type "kaddressbook" -> it switches to kaddressbook + 1d) type "kmail foo@kde.org" -> it opens a kmail composer, without switching + 1e) type "knode" -> it switches to knode + 1f) type "kaddressbook --new-contact" -> it opens a kaddressbook contact window + 1g) type "knode news://foobar/group" -> it pops up "can't resolve hostname" + + 2) close kontact. Launch kmail. Launch kontact again. + 2a) click "Mail" icon -> kontact doesn't load a part, but activates the kmail window + 2b) type "kmail foo@kde.org" -> standalone kmail opens composer. + 2c) close kmail, click "Mail" icon -> kontact loads the kmail part. + 2d) type "kmail" -> kontact is brought to front + + 3) close kontact. Launch korganizer, then kontact. + 3a) both Todo and Calendar activate the running korganizer. + 3b) type "korganizer" -> standalone korganizer is brought to front + 3c) close korganizer, click Calendar or Todo -> kontact loads part. + 3d) type "korganizer" -> kontact is brought to front + + 4) close kontact. Launch kaddressbook, then kontact. + 4a) "Contacts" icon activate the running kaddressbook. + 4b) type "kaddressbook" -> standalone kaddressbook is brought to front + 4c) close kaddressbook, type "kaddressbook -a foo@kde.org" -> kontact loads part and opens editor + 4d) type "kaddressbook" -> kontact is brought to front + + 5) close kontact. Launch knode, then kontact. + 5a) "News" icon activate the running knode. + 5b) type "knode" -> standalone knode is brought to front + 5c) close knode, type "knode news://foobar/group" -> kontact loads knode and pops up msgbox + 5d) type "knode" -> kontact is brought to front + + 6) start "kontact --module summaryplugin" + 6a) type "dcop kmail kmail newInstance" -> kontact switches to kmail (#103775) + 6b) type "kmail" -> kontact is brought to front + 6c) type "kontact" -> kontact is brought to front + 6d) type "kontact --module summaryplugin" -> kontact switches to summary + +*/ + +using namespace Kontact; + +int UniqueAppHandler::newInstance() +{ + // This bit is duplicated from KUniqueApplication::newInstance() + if ( kapp->mainWidget() ) { + kapp->mainWidget()->show(); + KWin::forceActiveWindow( kapp->mainWidget()->winId() ); + KStartupInfo::appStarted(); + } + + // Then ensure the part appears in kontact + mPlugin->core()->selectPlugin( mPlugin ); + return 0; +} + +bool UniqueAppHandler::process( const QCString &fun, const QByteArray &data, + QCString& replyType, QByteArray &replyData ) +{ + if ( fun == "newInstance()" ) { + replyType = "int"; + + KCmdLineArgs::reset(); // forget options defined by other "applications" + loadCommandLineOptions(); // implemented by plugin + + // This bit is duplicated from KUniqueApplication::processDelayed() + QDataStream ds( data, IO_ReadOnly ); + KCmdLineArgs::loadAppArgs( ds ); + if ( !ds.atEnd() ) { // backwards compatibility + QCString asn_id; + ds >> asn_id; + kapp->setStartupId( asn_id ); + } + + QDataStream _replyStream( replyData, IO_WriteOnly ); + _replyStream << newInstance(); + + // OK, we're done, reload the initial kontact command line options, + // so that "kontact --module foo" keeps working (#103775). + + KCmdLineArgs::reset(); // forget options defined above + loadKontactCommandLineOptions(); + + } else if ( fun == "load()" ) { + replyType = "bool"; + (void)mPlugin->part(); // load the part without bringing it to front + + QDataStream _replyStream( replyData, IO_WriteOnly ); + _replyStream << true; + } else { + return DCOPObject::process( fun, data, replyType, replyData ); + } + return true; +} + +QCStringList UniqueAppHandler::interfaces() +{ + QCStringList ifaces = DCOPObject::interfaces(); + ifaces += "Kontact::UniqueAppHandler"; + return ifaces; +} + +QCStringList UniqueAppHandler::functions() +{ + QCStringList funcs = DCOPObject::functions(); + funcs << "int newInstance()"; + funcs << "bool load()"; + return funcs; +} + +UniqueAppWatcher::UniqueAppWatcher( UniqueAppHandlerFactoryBase* factory, Plugin* plugin ) + : QObject( plugin ), mFactory( factory ), mPlugin( plugin ) +{ + // The app is running standalone if 1) that name is known to DCOP + mRunningStandalone = kapp->dcopClient()->isApplicationRegistered( plugin->name() ); + + // and 2) it's not registered by kontact (e.g. in another plugin) + if ( mRunningStandalone && kapp->dcopClient()->findLocalClient( plugin->name() ) ) + mRunningStandalone = false; + + if ( mRunningStandalone ) { + kapp->dcopClient()->setNotifications( true ); + connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString& ) ), + this, SLOT( unregisteredFromDCOP( const QCString& ) ) ); + } else { + mFactory->createHandler( mPlugin ); + } +} + +UniqueAppWatcher::~UniqueAppWatcher() +{ + if ( mRunningStandalone ) + kapp->dcopClient()->setNotifications( false ); + + delete mFactory; +} + +void UniqueAppWatcher::unregisteredFromDCOP( const QCString& appId ) +{ + if ( appId == mPlugin->name() && mRunningStandalone ) { + disconnect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString& ) ), + this, SLOT( unregisteredFromDCOP( const QCString& ) ) ); + kdDebug(5601) << k_funcinfo << appId << endl; + mFactory->createHandler( mPlugin ); + kapp->dcopClient()->setNotifications( false ); + mRunningStandalone = false; + } +} + +static KCmdLineOptions options[] = +{ + { "module <module>", I18N_NOOP( "Start with a specific Kontact module" ), 0 }, + { "iconify", I18N_NOOP( "Start in iconified (minimized) mode" ), 0 }, + { "list", I18N_NOOP( "List all possible modules and exit" ), 0 }, + KCmdLineLastOption +}; + +void Kontact::UniqueAppHandler::loadKontactCommandLineOptions() +{ + KCmdLineArgs::addCmdLineOptions( options ); + KUniqueApplication::addCmdLineOptions(); + KApplication::addCmdLineOptions(); +} + +#include "uniqueapphandler.moc" diff --git a/kontact/interfaces/uniqueapphandler.h b/kontact/interfaces/uniqueapphandler.h new file mode 100644 index 000000000..23a593af6 --- /dev/null +++ b/kontact/interfaces/uniqueapphandler.h @@ -0,0 +1,123 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 David Faure <faure@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KONTACT_UNIQUEAPPHANDLER_H +#define KONTACT_UNIQUEAPPHANDLER_H + +#include <dcopobject.h> +#include <plugin.h> +#include <kdepimmacros.h> + +namespace Kontact +{ + +/** + * DCOP Object that has the name of the standalone application (e.g. "kmail") + * and implements newInstance() so that running the separate application does + * the right thing when kontact is running. + * By default this means simply bringing the main window to the front, + * but newInstance can be reimplemented. + */ +class KDE_EXPORT UniqueAppHandler : public DCOPObject +{ + K_DCOP + + public: + UniqueAppHandler( Plugin* plugin ) : DCOPObject( plugin->name() ), mPlugin( plugin ) {} + + /// This must be reimplemented so that app-specific command line options can be parsed + virtual void loadCommandLineOptions() = 0; + + /// We can't use k_dcop and dcopidl here, because the data passed + /// to newInstance can't be expressed in terms of normal data types. + virtual int newInstance(); + + Plugin* plugin() const { return mPlugin; } + + /// Load the kontact command line options. + static void loadKontactCommandLineOptions(); + + private: + Plugin* mPlugin; +}; + +/// Base class for UniqueAppHandler +class UniqueAppHandlerFactoryBase +{ + public: + virtual UniqueAppHandler* createHandler( Plugin* ) = 0; +}; + +/** + * Used by UniqueAppWatcher below, to create the above UniqueAppHandler object + * when necessary. + * The template argument is the UniqueAppHandler-derived class. + * This allows to remove the need to subclass UniqueAppWatcher. + */ +template <class T> class UniqueAppHandlerFactory : public UniqueAppHandlerFactoryBase +{ + public: + virtual UniqueAppHandler* createHandler( Plugin* plugin ) { + (void)plugin->dcopClient(); // ensure that we take over the DCOP name + return new T( plugin ); + } +}; + + +/** + * If the standalone application is running by itself, we need to watch + * for when the user closes it, and activate the uniqueapphandler then. + * This prevents, on purpose, that the standalone app can be restarted. + * Kontact takes over from there. + * + */ +class KDE_EXPORT UniqueAppWatcher : public QObject +{ + Q_OBJECT + + public: + /** + * Create an instance of UniqueAppWatcher, which does everything necessary + * for the "unique application" behavior: create the UniqueAppHandler as soon + * as possible, i.e. either right now or when the standalone app is closed. + * + * @param factory templatized factory to create the handler. Example: + * ... Note that the watcher takes ownership of the factory. + * @param plugin is the plugin application + */ + UniqueAppWatcher( UniqueAppHandlerFactoryBase* factory, Plugin* plugin ); + + virtual ~UniqueAppWatcher(); + + bool isRunningStandalone() const { return mRunningStandalone; } + + protected slots: + void unregisteredFromDCOP( const QCString& appId ); + + private: + bool mRunningStandalone; + UniqueAppHandlerFactoryBase* mFactory; + Plugin* mPlugin; +}; + +} // namespace + +#endif /* KONTACT_UNIQUEAPPHANDLER_H */ diff --git a/kontact/pics/Makefile.am b/kontact/pics/Makefile.am new file mode 100644 index 000000000..5621c06e9 --- /dev/null +++ b/kontact/pics/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = icons + diff --git a/kontact/pics/icons/LICENSE b/kontact/pics/icons/LICENSE new file mode 100644 index 000000000..cca3687bf --- /dev/null +++ b/kontact/pics/icons/LICENSE @@ -0,0 +1,23 @@ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +This copyright and license notice covers the images in this directory. +Note the license notice contains an add-on. +************************************************************************ + +TITLE: Kontact Icons from NUVOLA ICON THEME +SITE: http://www.icon-king.com +DESC: These icon are for Kontact KDE groupware + +Copyright (c) 2004 David Vignoni. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation, +version 2.1 of the License. +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 +Lesser General Public License for more details. +You should have received a copy of the GNU Lesser General Public +License along with this library (see the the license.txt file); if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + diff --git a/kontact/pics/icons/Makefile.am b/kontact/pics/icons/Makefile.am new file mode 100644 index 000000000..e5515a859 --- /dev/null +++ b/kontact/pics/icons/Makefile.am @@ -0,0 +1 @@ +KDE_ICON = AUTO diff --git a/kontact/pics/icons/cr16-action-kontact_contacts.png b/kontact/pics/icons/cr16-action-kontact_contacts.png Binary files differnew file mode 100644 index 000000000..432b7d772 --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_contacts.png diff --git a/kontact/pics/icons/cr16-action-kontact_date.png b/kontact/pics/icons/cr16-action-kontact_date.png Binary files differnew file mode 100644 index 000000000..b4cddd67f --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_date.png diff --git a/kontact/pics/icons/cr16-action-kontact_journal.png b/kontact/pics/icons/cr16-action-kontact_journal.png Binary files differnew file mode 100644 index 000000000..112c58ca1 --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_journal.png diff --git a/kontact/pics/icons/cr16-action-kontact_mail.png b/kontact/pics/icons/cr16-action-kontact_mail.png Binary files differnew file mode 100644 index 000000000..39a420eeb --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_mail.png diff --git a/kontact/pics/icons/cr16-action-kontact_news.png b/kontact/pics/icons/cr16-action-kontact_news.png Binary files differnew file mode 100644 index 000000000..0cac21604 --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_news.png diff --git a/kontact/pics/icons/cr16-action-kontact_notes.png b/kontact/pics/icons/cr16-action-kontact_notes.png Binary files differnew file mode 100644 index 000000000..035507612 --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_notes.png diff --git a/kontact/pics/icons/cr16-action-kontact_summary.png b/kontact/pics/icons/cr16-action-kontact_summary.png Binary files differnew file mode 100644 index 000000000..29fbf64de --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_summary.png diff --git a/kontact/pics/icons/cr16-action-kontact_summary_green.png b/kontact/pics/icons/cr16-action-kontact_summary_green.png Binary files differnew file mode 100644 index 000000000..6ed951adf --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_summary_green.png diff --git a/kontact/pics/icons/cr16-action-kontact_todo.png b/kontact/pics/icons/cr16-action-kontact_todo.png Binary files differnew file mode 100644 index 000000000..db0dae30c --- /dev/null +++ b/kontact/pics/icons/cr16-action-kontact_todo.png diff --git a/kontact/pics/icons/cr22-action-kontact_contacts.png b/kontact/pics/icons/cr22-action-kontact_contacts.png Binary files differnew file mode 100644 index 000000000..d13a67bbe --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_contacts.png diff --git a/kontact/pics/icons/cr22-action-kontact_date.png b/kontact/pics/icons/cr22-action-kontact_date.png Binary files differnew file mode 100644 index 000000000..15c4a083c --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_date.png diff --git a/kontact/pics/icons/cr22-action-kontact_journal.png b/kontact/pics/icons/cr22-action-kontact_journal.png Binary files differnew file mode 100644 index 000000000..7e7f2d560 --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_journal.png diff --git a/kontact/pics/icons/cr22-action-kontact_mail.png b/kontact/pics/icons/cr22-action-kontact_mail.png Binary files differnew file mode 100644 index 000000000..168c4494c --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_mail.png diff --git a/kontact/pics/icons/cr22-action-kontact_news.png b/kontact/pics/icons/cr22-action-kontact_news.png Binary files differnew file mode 100644 index 000000000..805cae722 --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_news.png diff --git a/kontact/pics/icons/cr22-action-kontact_notes.png b/kontact/pics/icons/cr22-action-kontact_notes.png Binary files differnew file mode 100644 index 000000000..df7881cf8 --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_notes.png diff --git a/kontact/pics/icons/cr22-action-kontact_summary.png b/kontact/pics/icons/cr22-action-kontact_summary.png Binary files differnew file mode 100644 index 000000000..ae08595ca --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_summary.png diff --git a/kontact/pics/icons/cr22-action-kontact_summary_green.png b/kontact/pics/icons/cr22-action-kontact_summary_green.png Binary files differnew file mode 100644 index 000000000..0ede39bc7 --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_summary_green.png diff --git a/kontact/pics/icons/cr22-action-kontact_todo.png b/kontact/pics/icons/cr22-action-kontact_todo.png Binary files differnew file mode 100644 index 000000000..e193011c0 --- /dev/null +++ b/kontact/pics/icons/cr22-action-kontact_todo.png diff --git a/kontact/pics/icons/cr32-action-kontact_contacts.png b/kontact/pics/icons/cr32-action-kontact_contacts.png Binary files differnew file mode 100644 index 000000000..8f8b46052 --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_contacts.png diff --git a/kontact/pics/icons/cr32-action-kontact_date.png b/kontact/pics/icons/cr32-action-kontact_date.png Binary files differnew file mode 100644 index 000000000..127ea3298 --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_date.png diff --git a/kontact/pics/icons/cr32-action-kontact_journal.png b/kontact/pics/icons/cr32-action-kontact_journal.png Binary files differnew file mode 100644 index 000000000..e3a0dec54 --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_journal.png diff --git a/kontact/pics/icons/cr32-action-kontact_mail.png b/kontact/pics/icons/cr32-action-kontact_mail.png Binary files differnew file mode 100644 index 000000000..cf0c14799 --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_mail.png diff --git a/kontact/pics/icons/cr32-action-kontact_news.png b/kontact/pics/icons/cr32-action-kontact_news.png Binary files differnew file mode 100644 index 000000000..1d19073ea --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_news.png diff --git a/kontact/pics/icons/cr32-action-kontact_notes.png b/kontact/pics/icons/cr32-action-kontact_notes.png Binary files differnew file mode 100644 index 000000000..93a0059a3 --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_notes.png diff --git a/kontact/pics/icons/cr32-action-kontact_summary.png b/kontact/pics/icons/cr32-action-kontact_summary.png Binary files differnew file mode 100644 index 000000000..eb64a05ce --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_summary.png diff --git a/kontact/pics/icons/cr32-action-kontact_summary_green.png b/kontact/pics/icons/cr32-action-kontact_summary_green.png Binary files differnew file mode 100644 index 000000000..5d241e194 --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_summary_green.png diff --git a/kontact/pics/icons/cr32-action-kontact_todo.png b/kontact/pics/icons/cr32-action-kontact_todo.png Binary files differnew file mode 100644 index 000000000..bb960d901 --- /dev/null +++ b/kontact/pics/icons/cr32-action-kontact_todo.png diff --git a/kontact/pics/icons/cr48-action-kontact_contacts.png b/kontact/pics/icons/cr48-action-kontact_contacts.png Binary files differnew file mode 100644 index 000000000..c6bc5174d --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_contacts.png diff --git a/kontact/pics/icons/cr48-action-kontact_date.png b/kontact/pics/icons/cr48-action-kontact_date.png Binary files differnew file mode 100644 index 000000000..da1ca9408 --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_date.png diff --git a/kontact/pics/icons/cr48-action-kontact_journal.png b/kontact/pics/icons/cr48-action-kontact_journal.png Binary files differnew file mode 100644 index 000000000..f052f074f --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_journal.png diff --git a/kontact/pics/icons/cr48-action-kontact_mail.png b/kontact/pics/icons/cr48-action-kontact_mail.png Binary files differnew file mode 100644 index 000000000..092ad247e --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_mail.png diff --git a/kontact/pics/icons/cr48-action-kontact_news.png b/kontact/pics/icons/cr48-action-kontact_news.png Binary files differnew file mode 100644 index 000000000..1d725be21 --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_news.png diff --git a/kontact/pics/icons/cr48-action-kontact_notes.png b/kontact/pics/icons/cr48-action-kontact_notes.png Binary files differnew file mode 100644 index 000000000..81526ee80 --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_notes.png diff --git a/kontact/pics/icons/cr48-action-kontact_summary.png b/kontact/pics/icons/cr48-action-kontact_summary.png Binary files differnew file mode 100644 index 000000000..4c44fff1c --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_summary.png diff --git a/kontact/pics/icons/cr48-action-kontact_summary_green.png b/kontact/pics/icons/cr48-action-kontact_summary_green.png Binary files differnew file mode 100644 index 000000000..d07066532 --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_summary_green.png diff --git a/kontact/pics/icons/cr48-action-kontact_todo.png b/kontact/pics/icons/cr48-action-kontact_todo.png Binary files differnew file mode 100644 index 000000000..3868bddd6 --- /dev/null +++ b/kontact/pics/icons/cr48-action-kontact_todo.png diff --git a/kontact/pics/icons/cr64-action-kontact_contacts.png b/kontact/pics/icons/cr64-action-kontact_contacts.png Binary files differnew file mode 100644 index 000000000..a08e376c2 --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_contacts.png diff --git a/kontact/pics/icons/cr64-action-kontact_date.png b/kontact/pics/icons/cr64-action-kontact_date.png Binary files differnew file mode 100644 index 000000000..71d3c3596 --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_date.png diff --git a/kontact/pics/icons/cr64-action-kontact_journal.png b/kontact/pics/icons/cr64-action-kontact_journal.png Binary files differnew file mode 100644 index 000000000..b590a0a83 --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_journal.png diff --git a/kontact/pics/icons/cr64-action-kontact_mail.png b/kontact/pics/icons/cr64-action-kontact_mail.png Binary files differnew file mode 100644 index 000000000..b5bce381f --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_mail.png diff --git a/kontact/pics/icons/cr64-action-kontact_news.png b/kontact/pics/icons/cr64-action-kontact_news.png Binary files differnew file mode 100644 index 000000000..537fa1d13 --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_news.png diff --git a/kontact/pics/icons/cr64-action-kontact_notes.png b/kontact/pics/icons/cr64-action-kontact_notes.png Binary files differnew file mode 100644 index 000000000..1af15fce8 --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_notes.png diff --git a/kontact/pics/icons/cr64-action-kontact_summary.png b/kontact/pics/icons/cr64-action-kontact_summary.png Binary files differnew file mode 100644 index 000000000..2c47a2d26 --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_summary.png diff --git a/kontact/pics/icons/cr64-action-kontact_summary_green.png b/kontact/pics/icons/cr64-action-kontact_summary_green.png Binary files differnew file mode 100644 index 000000000..e8719e13a --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_summary_green.png diff --git a/kontact/pics/icons/cr64-action-kontact_todo.png b/kontact/pics/icons/cr64-action-kontact_todo.png Binary files differnew file mode 100644 index 000000000..055cafe0c --- /dev/null +++ b/kontact/pics/icons/cr64-action-kontact_todo.png diff --git a/kontact/plugins/Makefile.am b/kontact/plugins/Makefile.am new file mode 100644 index 000000000..986713b93 --- /dev/null +++ b/kontact/plugins/Makefile.am @@ -0,0 +1,6 @@ +if compile_kpilot +KPILOT_KONTACTPLUGIN = kpilot +endif + +SUBDIRS = $(KPILOT_KONTACTPLUGIN) kaddressbook kmail knotes korganizer \ + summary weather knode newsticker specialdates akregator karm diff --git a/kontact/plugins/akregator/Makefile.am b/kontact/plugins/akregator/Makefile.am new file mode 100644 index 000000000..d97f14341 --- /dev/null +++ b/kontact/plugins/akregator/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir)/akregator/src -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_akregator.la +libkontact_akregator_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_akregator_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) +libkontact_akregator_la_SOURCES = akregator_plugin.cpp akregator_partiface.stub + +METASOURCES = AUTO + +akregator_partiface_DIR = $(top_srcdir)/akregator/src + +servicedir = $(kde_servicesdir)/kontact +service_DATA = akregatorplugin.desktop akregatorplugin3.2.desktop + diff --git a/kontact/plugins/akregator/akregator_plugin.cpp b/kontact/plugins/akregator/akregator_plugin.cpp new file mode 100644 index 000000000..d57cea7f6 --- /dev/null +++ b/kontact/plugins/akregator/akregator_plugin.cpp @@ -0,0 +1,156 @@ +/* + This file is part of Akregator. + + Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qwidget.h> + +#include <dcopclient.h> +#include <dcopref.h> +#include <kaboutdata.h> +#include <kaction.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kparts/componentfactory.h> + +#include <core.h> +#include <plugin.h> + +#include <akregator_options.h> +#include <akregator_part.h> +#include "akregator_plugin.h" +namespace Akregator { + +typedef KGenericFactory<Akregator::Plugin, Kontact::Core > PluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_akregator, + PluginFactory( "kontact_akregator" ) ) + +Plugin::Plugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "akregator" ), m_stub(0) +{ + + setInstance( PluginFactory::instance() ); + + insertNewAction( new KAction( i18n( "New Feed..." ), "bookmark_add", CTRL+SHIFT+Key_F, this, SLOT( addFeed() ), actionCollection(), "feed_new" ) ); + + m_uniqueAppWatcher = new Kontact::UniqueAppWatcher( + new Kontact::UniqueAppHandlerFactory<Akregator::UniqueAppHandler>(), this ); +} + +Plugin::~Plugin() +{ +} + +bool Plugin::isRunningStandalone() +{ + return m_uniqueAppWatcher->isRunningStandalone(); +} + +QStringList Plugin::invisibleToolbarActions() const +{ + return QStringList( "file_new_contact" ); +} + + +Akregator::AkregatorPartIface_stub *Plugin::interface() +{ + if ( !m_stub ) { + part(); + } + + Q_ASSERT( m_stub ); + return m_stub; +} + + +MyBasePart* Plugin::createPart() +{ + MyBasePart* p = loadPart(); + + connect(p, SIGNAL(showPart()), this, SLOT(showPart())); + m_stub = new Akregator::AkregatorPartIface_stub( dcopClient(), "akregator", + "AkregatorIface" ); + m_stub->openStandardFeedList(); + return p; +} + + +void Plugin::showPart() +{ + core()->selectPlugin(this); +} + +void Plugin::addFeed() +{ + interface()->addFeed(); +} + +QStringList Plugin::configModules() const +{ + QStringList modules; + modules << "PIM/akregator.desktop"; + return modules; +} + +void Plugin::readProperties( KConfig *config ) +{ + if ( part() ) { + Akregator::Part *myPart = static_cast<Akregator::Part*>( part() ); + myPart->readProperties( config ); + } +} + +void Plugin::saveProperties( KConfig *config ) +{ + if ( part() ) { + Akregator::Part *myPart = static_cast<Akregator::Part*>( part() ); + myPart->saveProperties( config ); + } +} + +void UniqueAppHandler::loadCommandLineOptions() +{ + KCmdLineArgs::addCmdLineOptions( akregator_options ); +} + +int UniqueAppHandler::newInstance() +{ + kdDebug(5602) << k_funcinfo << endl; + // Ensure part is loaded + (void)plugin()->part(); + DCOPRef akr( "akregator", "AkregatorIface" ); +// DCOPReply reply = kAB.call( "handleCommandLine" ); + // if ( reply.isValid() ) { + // bool handled = reply; + // kdDebug(5602) << k_funcinfo << "handled=" << handled << endl; + // if ( !handled ) // no args -> simply bring kaddressbook plugin to front + return Kontact::UniqueAppHandler::newInstance(); + // } + // return 0; +} + +} // namespace Akregator +#include "akregator_plugin.moc" diff --git a/kontact/plugins/akregator/akregator_plugin.h b/kontact/plugins/akregator/akregator_plugin.h new file mode 100644 index 000000000..af1a905f9 --- /dev/null +++ b/kontact/plugins/akregator/akregator_plugin.h @@ -0,0 +1,81 @@ +/* + This file is part of Akregator. + + Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef AKREGATOR_PLUGIN_H +#define AKREGATOR_PLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include <kparts/part.h> +#include <plugin.h> +#include "akregator_partiface_stub.h" +#include <uniqueapphandler.h> + +class KAboutData; + +namespace Akregator { + +typedef KParts::ReadOnlyPart MyBasePart; + +class UniqueAppHandler : public Kontact::UniqueAppHandler +{ + public: + UniqueAppHandler( Kontact::Plugin* plugin ) : Kontact::UniqueAppHandler( plugin ) {} + virtual void loadCommandLineOptions(); + virtual int newInstance(); +}; + + +class Plugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + Plugin( Kontact::Core *core, const char *name, + const QStringList & ); + ~Plugin(); + + int weight() const { return 700; } + + AkregatorPartIface_stub *interface(); + + virtual QStringList configModules() const; + virtual QStringList invisibleToolbarActions() const; + virtual bool isRunningStandalone(); + virtual void readProperties( KConfig *config ); + virtual void saveProperties( KConfig *config ); + + private slots: + void showPart(); + void addFeed(); + + protected: + MyBasePart *createPart(); + AkregatorPartIface_stub *m_stub; + Kontact::UniqueAppWatcher *m_uniqueAppWatcher; +}; + +} // namespace Akregator +#endif diff --git a/kontact/plugins/akregator/akregatorplugin.desktop b/kontact/plugins/akregator/akregatorplugin.desktop new file mode 100644 index 000000000..015ae80a1 --- /dev/null +++ b/kontact/plugins/akregator/akregatorplugin.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Type=Service +Icon=akregator +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_akregator +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libakregatorpart +X-KDE-KontactPartLoadOnStart=false + +X-KDE-PluginInfo-Name=kontact_akregator +X-KDE-PluginInfo-Version=1.0b2 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Feed Reader Component (Akregator Plugin) +Comment[bg]=Приставка за Akregator +Comment[ca]=Component lector d'enllaços (endollable de l'Akregator) +Comment[da]=Feed-læserkomponent (Akregator-plugin) +Comment[de]=News-Leser (Akregator-Modul) +Comment[el]=Συστατικό ανάγνωσης ροών (Πρόσθετο του Akregator) +Comment[es]=Componente de lectura de fuentes (complemento de Akregator) +Comment[et]=Uudistevoogude plugin (Akregator) +Comment[fr]=Composant du lecteur de flux (Module pour Akregator) +Comment[is]=Fréttastraumalestur (Akregator íforrit) +Comment[it]=Componente lettore fonti (plugin Akregator) +Comment[ja]=フィードリーダーコンポーネント (Akregator プラグイン) +Comment[km]=មមាសភាគកម្មវិធីអានមតិព័ត៌មាន (កម្មវិធីជំនួយ Akregator) +Comment[nds]=Stroomleser-Komponent (Akregator-Moduul) +Comment[nl]=Component om feeds te lezen (Akregator-plugin) +Comment[pl]=Składnik do czytania kanałów RSS (wtyczka Akregator) +Comment[ru]=Просмотр лент новостей (модуль Akregator) +Comment[sk]=Komponent na čítanie kanálov (Modul pre Akregator) +Comment[sr]=Компонента читања довода (прикључак Akregator-а) +Comment[sr@Latn]=Komponenta čitanja dovoda (priključak Akregator-a) +Comment[sv]=Komponent för läsning av kanaler (Akregator-insticksprogram) +Comment[tr]=Kaynak Okuyucu Bileşeni (Akregator Eklentisi) +Comment[zh_CN]=新闻源阅读器组件(Akregator 插件) +Comment[zh_TW]=Feed 閱讀器組件(Akregator 外掛程式) +Name=Feeds +Name[af]=Strome +Name[bg]=Новини +Name[ca]=Enllaços +Name[cs]=Kanály +Name[da]=Kilder +Name[de]=Nachrichten +Name[el]=Ροές +Name[eo]=Fluoj +Name[es]=Orígenes +Name[et]=Uudisevood +Name[eu]=Iturriak +Name[fa]=خوراندنها +Name[fi]=Syötteet +Name[fr]=Flux +Name[fy]=Nijsoanfier +Name[ga]=Fothaí +Name[gl]=Fontes +Name[he]=ערוצים +Name[hu]=Hírforrások +Name[is]=Fréttastraumar +Name[it]=Fonti +Name[ja]=フィード +Name[ka]=კვება +Name[kk]=Ақпарлар +Name[km]=មតិព័ត៌មាន +Name[lt]=Kanalai +Name[ms]=Suapan +Name[nb]=Kanaler +Name[nds]=Narichtenströöm +Name[ne]=फिड +Name[nn]=Kanalar +Name[pl]=Kanały +Name[pt]=Fontes +Name[pt_BR]=Fontes de Notícias +Name[ru]=Ленты новостей +Name[sk]=Kanály +Name[sl]=Viri +Name[sr]=Доводи +Name[sr@Latn]=Dovodi +Name[sv]=Kanaler +Name[ta]=உள்ளீடுகள் +Name[tr]=Haberler +Name[uk]=Подачі +Name[uz]=Yangiliklar tasmalari +Name[uz@cyrillic]=Янгиликлар тасмалари +Name[zh_CN]=种子 + diff --git a/kontact/plugins/akregator/akregatorplugin3.2.desktop b/kontact/plugins/akregator/akregatorplugin3.2.desktop new file mode 100644 index 000000000..7bd29ffbc --- /dev/null +++ b/kontact/plugins/akregator/akregatorplugin3.2.desktop @@ -0,0 +1,112 @@ +[Desktop Entry] +Type=Service +Icon=akregator +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_akregator +X-KDE-KontactPluginVersion=3 +X-KDE-KontactPartLibraryName=libakregatorpart + +X-KDE-PluginInfo-Name=kontact_akregator +X-KDE-PluginInfo-Version=1.0b2 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Akregator Plugin +Comment[af]=Akregator inprop module +Comment[bg]=Приставка за Akregator +Comment[br]=Lugant Akregator +Comment[ca]=Endollable Akregator +Comment[cs]=Modul Akregatoru +Comment[de]=Akregator-Modul +Comment[el]=Πρόσθετο του Akregator +Comment[eo]=Akregator-kromaĵo +Comment[es]=Extensión de Akregator +Comment[et]=Akregatori plugin +Comment[eu]=Akregator plugin-a +Comment[fa]=وصلۀ Akregator +Comment[fi]=Akregator-liitännäinen +Comment[fr]=Module pour Akregator +Comment[fy]=Akregatorplugin +Comment[ga]=Breiseán Akregator +Comment[gl]=Extensión para Akregator +Comment[he]=תוסף עבור Akregator +Comment[hu]=Akregator bővítőmodul +Comment[is]=Akregator íforrit +Comment[it]=Plugin aKregator +Comment[ja]=Akregator プラグイン +Comment[ka]=Akregator-ის მოდული +Comment[kk]=Akregator модулі +Comment[km]=កម្មវិធីជំនួយ Akregator +Comment[lt]=Akregator priedas +Comment[mk]=Приклучок за Akregator +Comment[ms]=Plugin Akregator +Comment[nb]=Akgregator-programtillegg +Comment[nds]=Akregator-Moduul +Comment[ne]=एक्रिगेटर प्लगइन +Comment[nl]=Akregatorplugin +Comment[nn]=Akregator-programtillegg +Comment[pl]=Wtyczka Akregatora +Comment[pt]='Plugin' Akregator +Comment[pt_BR]=Plug-in do Akregator +Comment[ru]=Модуль Akregator +Comment[sk]=Modul Akregator +Comment[sl]=Vstavek Akregator +Comment[sr]=Прикључак Akregator-а +Comment[sr@Latn]=Priključak Akregator-a +Comment[sv]=Akregator-insticksprogram +Comment[ta]=Akregator சொருகுப்பொருள் +Comment[tr]=Akregator Eklentisi +Comment[uk]=Втулок Akregator +Comment[uz]=Akregator plagini +Comment[uz@cyrillic]=Akregator плагини +Comment[zh_CN]=Akregator 插件 +Comment[zh_TW]=Akregator 外掛程式 +Name=Feeds +Name[af]=Strome +Name[bg]=Новини +Name[ca]=Enllaços +Name[cs]=Kanály +Name[da]=Kilder +Name[de]=Nachrichten +Name[el]=Ροές +Name[eo]=Fluoj +Name[es]=Orígenes +Name[et]=Uudisevood +Name[eu]=Iturriak +Name[fa]=خوراندنها +Name[fi]=Syötteet +Name[fr]=Flux +Name[fy]=Nijsoanfier +Name[ga]=Fothaí +Name[gl]=Fontes +Name[he]=ערוצים +Name[hu]=Hírforrások +Name[is]=Fréttastraumar +Name[it]=Fonti +Name[ja]=フィード +Name[ka]=კვება +Name[kk]=Ақпарлар +Name[km]=មតិព័ត៌មាន +Name[lt]=Kanalai +Name[ms]=Suapan +Name[nb]=Kanaler +Name[nds]=Narichtenströöm +Name[ne]=फिड +Name[nn]=Kanalar +Name[pl]=Kanały +Name[pt]=Fontes +Name[pt_BR]=Fontes de Notícias +Name[ru]=Ленты новостей +Name[sk]=Kanály +Name[sl]=Viri +Name[sr]=Доводи +Name[sr@Latn]=Dovodi +Name[sv]=Kanaler +Name[ta]=உள்ளீடுகள் +Name[tr]=Haberler +Name[uk]=Подачі +Name[uz]=Yangiliklar tasmalari +Name[uz@cyrillic]=Янгиликлар тасмалари +Name[zh_CN]=种子 + diff --git a/kontact/plugins/kaddressbook/Makefile.am b/kontact/plugins/kaddressbook/Makefile.am new file mode 100644 index 000000000..a769f29d8 --- /dev/null +++ b/kontact/plugins/kaddressbook/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_kaddressbookplugin.la +libkontact_kaddressbookplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -lkabc +libkontact_kaddressbookplugin_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(top_builddir)/libkdepim/libkdepim.la + +libkontact_kaddressbookplugin_la_SOURCES = kaddressbook_plugin.cpp \ + kaddressbookiface.stub \ + kmailIface.stub + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = kaddressbookplugin.desktop + +kaddressbookiface_DIR = $(top_srcdir)/kaddressbook +kmailIface_DIR = $(top_srcdir)/kmail +kmailIface_DCOPIDLNG = true diff --git a/kontact/plugins/kaddressbook/kaddressbook_plugin.cpp b/kontact/plugins/kaddressbook/kaddressbook_plugin.cpp new file mode 100644 index 000000000..e2f5a706f --- /dev/null +++ b/kontact/plugins/kaddressbook/kaddressbook_plugin.cpp @@ -0,0 +1,218 @@ +/* + This file is part of Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qwidget.h> +#include <qdragobject.h> + +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kparts/componentfactory.h> + +#include <kaddrbook.h> +#include <kabc/addressbook.h> +#include <kabc/stdaddressbook.h> + +#include <dcopclient.h> +#include "kmailIface_stub.h" + +#include <libkdepim/maillistdrag.h> + +#include "core.h" +#include "plugin.h" + +#include "kaddressbook_plugin.h" + +typedef KGenericFactory< KAddressbookPlugin, Kontact::Core > KAddressbookPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_kaddressbookplugin, + KAddressbookPluginFactory( "kontact_kaddressbookplugin" ) ) + +KAddressbookPlugin::KAddressbookPlugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "kaddressbook" ), + mStub( 0 ) +{ + setInstance( KAddressbookPluginFactory::instance() ); + + insertNewAction( new KAction( i18n( "New Contact..." ), "identity", + CTRL+SHIFT+Key_C, this, SLOT( slotNewContact() ), actionCollection(), + "new_contact" ) ); + + insertNewAction( new KAction( i18n( "&New Distribution List..." ), "kontact_contacts", 0, this, + SLOT( slotNewDistributionList() ), actionCollection(), "new_distributionlist" ) ); + + insertSyncAction( new KAction( i18n( "Synchronize Contacts" ), "reload", + 0, this, SLOT( slotSyncContacts() ), actionCollection(), + "kaddressbook_sync" ) ); + mUniqueAppWatcher = new Kontact::UniqueAppWatcher( + new Kontact::UniqueAppHandlerFactory<KABUniqueAppHandler>(), this ); +} + +KAddressbookPlugin::~KAddressbookPlugin() +{ +} + +KParts::ReadOnlyPart* KAddressbookPlugin::createPart() +{ + KParts::ReadOnlyPart * part = loadPart(); + if ( !part ) return 0; + + // Create the stub that allows us to talk to the part + mStub = new KAddressBookIface_stub( dcopClient(), "kaddressbook", + "KAddressBookIface" ); + return part; +} + +QStringList KAddressbookPlugin::configModules() const +{ + QStringList modules; + modules << "PIM/kabconfig.desktop" << "PIM/kabldapconfig.desktop"; + return modules; +} + +QStringList KAddressbookPlugin::invisibleToolbarActions() const +{ + return QStringList( "file_new_contact" ); +} + +KAddressBookIface_stub *KAddressbookPlugin::interface() +{ + if ( !mStub ) { + part(); + } + Q_ASSERT( mStub ); + return mStub; +} + +void KAddressbookPlugin::slotNewContact() +{ + interface()->newContact(); +} + + +void KAddressbookPlugin::slotNewDistributionList() +{ + interface()->newDistributionList(); +} + +void KAddressbookPlugin::slotSyncContacts() +{ + DCOPRef ref( "kmail", "KMailICalIface" ); + ref.send( "triggerSync", QString("Contact") ); +} + +bool KAddressbookPlugin::createDCOPInterface( const QString& serviceType ) +{ + if ( serviceType == "DCOP/AddressBook" ) { + Q_ASSERT( mStub ); + return true; + } + + return false; +} + +void KAddressbookPlugin::configUpdated() +{ +} + +bool KAddressbookPlugin::isRunningStandalone() +{ + return mUniqueAppWatcher->isRunningStandalone(); +} + +bool KAddressbookPlugin::canDecodeDrag( QMimeSource *mimeSource ) +{ + return QTextDrag::canDecode( mimeSource ) || + KPIM::MailListDrag::canDecode( mimeSource ); +} + +#include <dcopref.h> + +void KAddressbookPlugin::processDropEvent( QDropEvent *event ) +{ + KPIM::MailList mails; + if ( KPIM::MailListDrag::decode( event, mails ) ) { + if ( mails.count() != 1 ) { + KMessageBox::sorry( core(), + i18n( "Drops of multiple mails are not supported." ) ); + } else { + KPIM::MailSummary mail = mails.first(); + + KMailIface_stub kmailIface( "kmail", "KMailIface" ); + QString sFrom = kmailIface.getFrom( mail.serialNumber() ); + + if ( !sFrom.isEmpty() ) { + KAddrBookExternal::addEmail( sFrom, core() ); + } + } + return; + } + + KMessageBox::sorry( core(), i18n( "Cannot handle drop events of type '%1'." ) + .arg( event->format() ) ); +} + + +void KAddressbookPlugin::loadProfile( const QString& directory ) +{ + DCOPRef ref( "kaddressbook", "KAddressBookIface" ); + ref.send( "loadProfile", directory ); +} + +void KAddressbookPlugin::saveToProfile( const QString& directory ) const +{ + DCOPRef ref( "kaddressbook", "KAddressBookIface" ); + ref.send( "saveToProfile", directory ); +} + +//// + +#include "../../../kaddressbook/kaddressbook_options.h" + +void KABUniqueAppHandler::loadCommandLineOptions() +{ + KCmdLineArgs::addCmdLineOptions( kaddressbook_options ); +} + +int KABUniqueAppHandler::newInstance() +{ + kdDebug(5602) << k_funcinfo << endl; + // Ensure part is loaded + (void)plugin()->part(); + DCOPRef kAB( "kaddressbook", "KAddressBookIface" ); + DCOPReply reply = kAB.call( "handleCommandLine" ); + if ( reply.isValid() ) { + bool handled = reply; + kdDebug(5602) << k_funcinfo << "handled=" << handled << endl; + if ( !handled ) // no args -> simply bring kaddressbook plugin to front + return Kontact::UniqueAppHandler::newInstance(); + } + return 0; +} + +#include "kaddressbook_plugin.moc" + +// vim: sw=2 sts=2 tw=80 et diff --git a/kontact/plugins/kaddressbook/kaddressbook_plugin.h b/kontact/plugins/kaddressbook/kaddressbook_plugin.h new file mode 100644 index 000000000..f66d44aaf --- /dev/null +++ b/kontact/plugins/kaddressbook/kaddressbook_plugin.h @@ -0,0 +1,86 @@ +/* + This file is part of Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KADDRESSBOOK_PLUGIN_H +#define KADDRESSBOOK_PLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include "kaddressbookiface_stub.h" +#include "plugin.h" +#include <uniqueapphandler.h> + +class KAboutData; + +class KABUniqueAppHandler : public Kontact::UniqueAppHandler +{ +public: + KABUniqueAppHandler( Kontact::Plugin* plugin ) : Kontact::UniqueAppHandler( plugin ) {} + virtual void loadCommandLineOptions(); + virtual int newInstance(); +}; + +class KAddressbookPlugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + KAddressbookPlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~KAddressbookPlugin(); + + virtual bool createDCOPInterface( const QString &serviceType ); + virtual bool isRunningStandalone(); + int weight() const { return 300; } + + bool canDecodeDrag( QMimeSource * ); + void processDropEvent( QDropEvent * ); + + virtual QStringList configModules() const; + + virtual QStringList invisibleToolbarActions() const; + + virtual void configUpdated(); + + KAddressBookIface_stub *interface(); + + //override + void loadProfile( const QString& directory ); + + //override + void saveToProfile( const QString& directory ) const; + + protected: + KParts::ReadOnlyPart *createPart(); + private slots: + void slotNewContact(); + void slotNewDistributionList(); + void slotSyncContacts(); + + private: + KAddressBookIface_stub *mStub; + Kontact::UniqueAppWatcher *mUniqueAppWatcher; +}; + +#endif diff --git a/kontact/plugins/kaddressbook/kaddressbookplugin.desktop b/kontact/plugins/kaddressbook/kaddressbookplugin.desktop new file mode 100644 index 000000000..f5208ea52 --- /dev/null +++ b/kontact/plugins/kaddressbook/kaddressbookplugin.desktop @@ -0,0 +1,100 @@ +[Desktop Entry] +Type=Service +Icon=kontact_contacts +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_kaddressbookplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libkaddressbookpart +X-KDE-KontactPartExecutableName=kaddressbook +X-KDE-KontactPluginHasSummary=false + +X-KDE-PluginInfo-Website=http://www.kaddressbook.org/ +X-KDE-PluginInfo-Name=kontact_kaddressbookplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Contacts Component (KAdressbook Plugin) +Comment[bg]=Приставка за адресника +Comment[ca]=Component de contactes (endollable del KAdressbook) +Comment[da]=Kontaktkomponent (KAddressbook-plugin) +Comment[de]=Kontakte-Komponente (Adressbuch-Modul) +Comment[el]=Συστατικό επαφών (Πρόσθετο του KAdressbook) +Comment[es]=Componente de contactos (complemento de KAddressbook) +Comment[et]=Kontaktide plugin (KDE aadressiraamat) +Comment[fr]=Composant des contacts (module externe KAdressBook) +Comment[is]=Vistfangaskráreining (KAddressBook íforrit) +Comment[it]=Componente contatti (plugin KAddressbook) +Comment[ja]=アドレス帳コンポーネント (KAddressbook プラグイン) +Comment[km]=សមាសភាគទំនាក់ទំនង (កម្មវិធីជំនួយ KAdressbook) +Comment[nds]=Kontakten-Komponent (KAddressbook-Moduul) +Comment[nl]=Adresboekcomponent (KAddressbook-plugin) +Comment[pl]=Składnik wizytówek (wtyczka KAddressBook) +Comment[ru]=Контакты (модуль KAddressBook) +Comment[sr]=Компонента контаката (прикључак KAddressBook-а) +Comment[sr@Latn]=Komponenta kontakata (priključak KAddressBook-a) +Comment[sv]=Kontaktkomponent (adressboksinsticksprogram) +Comment[tr]=Kişiler Bileşeni (KAdresDefteri Eklentisi) +Comment[zh_CN]=联系人组件(KAddressbook 插件) +Comment[zh_TW]=聯絡人組件(KAddressBook 外掛程式) +Name=Contacts +Name[af]=Kontakte +Name[ar]=المراسلون +Name[be]=Кантакты +Name[bg]=Контакти +Name[br]=Darempredoù +Name[bs]=Kontakti +Name[ca]=Contactes +Name[cs]=Kontakty +Name[cy]=Cysylltau +Name[da]=Kontakter +Name[de]=Kontakte +Name[el]=Επαφές +Name[eo]=Kontaktoj +Name[es]=Contactos +Name[et]=Kontaktid +Name[eu]=Kontaktuak +Name[fa]=تماسها +Name[fi]=Yhteystiedot +Name[fy]=Adressen +Name[ga]=Teagmhálacha +Name[gl]=Contactos +Name[he]=אנשי קשר +Name[hi]=सम्पर्कों +Name[hu]=Névjegyek +Name[is]=Tengiliðir +Name[it]=Contatti +Name[ja]=コンタクト +Name[ka]=კონტაქტები +Name[kk]=Контакттар +Name[km]=ទំនាក់ទំនង +Name[lt]=Kontaktai +Name[mk]=Контакти +Name[ms]=Orang hubungan +Name[nds]=Kontakten +Name[ne]=सम्पर्क +Name[nl]=Adressen +Name[nn]=Kontaktar +Name[pa]=ਸੰਪਰਕ +Name[pl]=Wizytówki +Name[pt]=Contactos +Name[pt_BR]=Contatos +Name[ro]=Contacte +Name[ru]=Контакты +Name[rw]=Amaderesi +Name[se]=Oktavuođat +Name[sk]=Kontakty +Name[sl]=Stiki +Name[sr]=Контакти +Name[sr@Latn]=Kontakti +Name[sv]=Kontakter +Name[ta]=தொடர்புகள் +Name[tg]=Алоқот +Name[th]=ที่อยู่ติดต่อ +Name[tr]=Kişiler +Name[uk]=Контакти +Name[uz]=Aloqalar +Name[uz@cyrillic]=Алоқалар +Name[zh_CN]=联系人 +Name[zh_TW]=聯絡人 diff --git a/kontact/plugins/karm/Makefile.am b/kontact/plugins/karm/Makefile.am new file mode 100644 index 000000000..e3fb02276 --- /dev/null +++ b/kontact/plugins/karm/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir)/karm -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_karm.la +libkontact_karm_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_karm_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la + +libkontact_karm_la_SOURCES = karm_plugin.cpp karmdcopiface.stub + +METASOURCES = AUTO + +karmdcopiface_DIR = $(top_srcdir)/karm + +servicedir = $(kde_servicesdir)/kontact +service_DATA = karmplugin.desktop + +DISTCLEANFILES = karmdcopiface.h karmdcopiface.stub diff --git a/kontact/plugins/karm/karm_plugin.cpp b/kontact/plugins/karm/karm_plugin.cpp new file mode 100644 index 000000000..a3a9d277d --- /dev/null +++ b/kontact/plugins/karm/karm_plugin.cpp @@ -0,0 +1,71 @@ +/* + This file is part of Kontact. + + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + adapted for karm 2005 by Thorsten Staerk <kde@staerk.de> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <kgenericfactory.h> +#include <kparts/componentfactory.h> + +#include "core.h" +#include "plugin.h" + +#include "karm_plugin.h" +#include "karmdcopiface_stub.h" + +typedef KGenericFactory<KarmPlugin, Kontact::Core> KarmPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_karm, + KarmPluginFactory( "kontact_karm" ) ) + +KarmPlugin::KarmPlugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "KArm" ) +{ + setInstance( KarmPluginFactory::instance() ); + (void)dcopClient(); + insertNewAction( new KAction( i18n( "New Task" ), "karm", + CTRL+SHIFT+Key_W, this, SLOT( newTask() ), actionCollection(), + "new_task" ) ); +} + +KarmPlugin::~KarmPlugin() +{ +} + +KParts::ReadOnlyPart* KarmPlugin::createPart() +{ + KParts::ReadOnlyPart * part = loadPart(); + if ( !part ) return 0; + + // this calls a DCOP interface from karm via the lib KarmDCOPIface_stub that is generated automatically + mStub = new KarmDCOPIface_stub( dcopClient(), "KArm", + "KarmDCOPIface" ); + + return part; +} + +void KarmPlugin::newTask() +{ + kdDebug() << "Entering newTask" << endl; + mStub->addTask("New Task"); +} + +#include "karm_plugin.moc" diff --git a/kontact/plugins/karm/karm_plugin.h b/kontact/plugins/karm/karm_plugin.h new file mode 100644 index 000000000..c5ef3e289 --- /dev/null +++ b/kontact/plugins/karm/karm_plugin.h @@ -0,0 +1,57 @@ +/* + This file is part of Kontact. + + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + adapted for karm 2005 by Thorsten Staerk <kde@staerk.de> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KARM_PLUGIN_H +#define KARM_PLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> +#include "karmdcopiface_stub.h" + +#include "plugin.h" + +class KAboutData; + +class KarmPlugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + KarmPlugin( Kontact::Core *core, const char *name, + const QStringList & ); + ~KarmPlugin(); + + int weight() const { return 700; } + + protected: + KParts::ReadOnlyPart *createPart(); + KarmDCOPIface_stub *mStub; + + public slots: + void newTask(); + +}; + +#endif diff --git a/kontact/plugins/karm/karmplugin.desktop b/kontact/plugins/karm/karmplugin.desktop new file mode 100644 index 000000000..469989fe6 --- /dev/null +++ b/kontact/plugins/karm/karmplugin.desktop @@ -0,0 +1,59 @@ +[Desktop Entry] +Type=Service +Icon=karm +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_karm +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libkarmpart + +X-KDE-PluginInfo-Name=kontact_karm +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=false + +Comment=Time Tracker Component (KArm Plugin) +Comment[bg]=Приставка за KArm +Comment[ca]=Component de seguiment dels temps (endollable del KArm) +Comment[da]=Time Tracker-komponent (KArm-plugin) +Comment[de]=Zeitplaner-Komponente (KArm-Modul) +Comment[el]=Συστατικό γραμμής χρόνου (Πρόσθετο του KArm) +Comment[es]=Componente de seguimiento de tiempos (complemento de KArm) +Comment[et]=Ajaarvestaja plugin (KArm) +Comment[fr]=Composant de suivi temporel (Module pour KArm) +Comment[is]=Tímastjórnunareining (KArm íforrit) +Comment[it]=Componente segna-tempo (plugin Karm) +Comment[ja]=タイムトラッカーコンポーネント (KArm プラグイン) +Comment[km]=សមាសភាគកម្មវិធីតាមដានពេលវេលា (កម្មវិធីជំនួយ KArm) +Comment[nds]=Tietlogbook-Komponent (KArm-Moduul) +Comment[nl]=Tijdsregistratiecomponent (KArm-plugin) +Comment[pl]=Składnik śledzenia czasu (wtyczka KArm) +Comment[ru]=Отслеживание времени (модуль KArm) +Comment[sr]=Компонента праћења времена (прикључак KArm-а) +Comment[sr@Latn]=Komponenta praćenja vremena (priključak KArm-a) +Comment[sv]=Komponent för tidmätning (Karm-insticksprogram) +Comment[tr]=Zaman İzleyici Bileşeni (KArm Eklentisi) +Comment[zh_CN]=时间追踪组件(KArm 插件) +Comment[zh_TW]=時間追蹤器組件(KArm 外掛程式) + +Name=Timer +Name[bg]=Таймер +Name[ca]=Cronòmetre +Name[de]=Stoppuhr +Name[el]=Χρονόμετρο +Name[es]=Temporizador +Name[et]=Ajaarvestaja +Name[fr]=Minuteur +Name[is]=Tímamælir +Name[ja]=タイマー +Name[km]=កម្មវិធីកំណត់ពេលវេលា +Name[nds]=Tietgever +Name[nl]=Tijdklok +Name[pl]=Stoper +Name[ru]=Таймер +Name[sk]=Časovač +Name[sr]=Тајмер +Name[sr@Latn]=Tajmer +Name[sv]=Tidmätning +Name[zh_CN]=计时器 +Name[zh_TW]=計時器 diff --git a/kontact/plugins/kitchensync/Makefile.am b/kontact/plugins/kitchensync/Makefile.am new file mode 100644 index 000000000..c6df9113f --- /dev/null +++ b/kontact/plugins/kitchensync/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces $(all_includes) + +kde_module_LTLIBRARIES = libkontact_kitchensync.la +libkontact_kitchensync_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_kitchensync_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la + +libkontact_kitchensync_la_SOURCES = kitchensync_plugin.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = kitchensync.desktop + +kitchensynciface_DIR = $(top_srcdir)/kitchensync diff --git a/kontact/plugins/kitchensync/kitchensync.desktop b/kontact/plugins/kitchensync/kitchensync.desktop new file mode 100644 index 000000000..0b1ac5078 --- /dev/null +++ b/kontact/plugins/kitchensync/kitchensync.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Icon=kitchensync +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_kitchensync +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libkitchensyncpart + +X-KDE-PluginInfo-Name=kontact_kitchensync +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=false + +Comment=Synchronization Component (Kitchensynk Plugin) +Comment[bg]=Приставка за синхронизация +Comment[ca]=Component de sincronització (endollable del KitchenSync) +Comment[da]=Synkronisergingskomponent (Kitchensync-plugin) +Comment[de]=Abgleich-Komponente (KitchenSync-Modul) +Comment[el]=Συστατικό συγχρονισμού (Πρόσθετο του Kitchensynk) +Comment[en_GB]=Synchronisation Component (Kitchensynk Plugin) +Comment[es]=Componente de sincronización (complemento de KitchenSync) +Comment[et]=Sünkroniseerimise plugin (KitchenSync) +Comment[fr]=Composant de synchronisation (Module KitchenSync) +Comment[is]=Samstillingareining (KitchenSync íforrit) +Comment[it]=Componente di sincronizzazione (plugin KitchenSync) +Comment[ja]=同期コンポーネント (KitchenSync プラグイン) +Comment[km]=ការធ្វើសមកាលកម្មសមាសភាគ (កម្មវិធីជំនួយ Kitchensynk) +Comment[nds]=Synkroniseer-Komponent (Kitchensynk-Moduul) +Comment[nl]=Synchronisatiecomponent (Kitchensynk-plugin) +Comment[pl]=Składnik synchronizacji (wtyczka KitchenSync) +Comment[ru]=Синхронизация (модуль KitchenSync) +Comment[sk]=Synchronizačný komponent (Modul pre Kitchensynk) +Comment[sr]=Компонента синхронизације (прикључак KitchenSync-а) +Comment[sr@Latn]=Komponenta sinhronizacije (priključak KitchenSync-a) +Comment[sv]=Synkroniseringskomponent (Kitchensynk-insticksprogram) +Comment[tr]=Eşzamanlama Eklentisi (Kitchensynk Eklentisi) +Comment[zh_CN]=同步组件(KitchenSync 插件) +Comment[zh_TW]=同步組件(KitchenSynk 外掛程式) +Name=Sync +Name[bg]=Синхронизация +Name[de]=Abgleich +Name[el]=Συγχρονισμός +Name[et]=Sünkroniseerimine +Name[fr]=Synchroniser +Name[is]=Samstilling +Name[ja]=同期 +Name[nds]=Synkroniseren +Name[pl]=Synchronizacja +Name[ru]=Синхронизация +Name[sv]=Synkronisering +Name[zh_TW]=同步 diff --git a/kontact/plugins/kitchensync/kitchensync_plugin.cpp b/kontact/plugins/kitchensync/kitchensync_plugin.cpp new file mode 100644 index 000000000..4de6cf8da --- /dev/null +++ b/kontact/plugins/kitchensync/kitchensync_plugin.cpp @@ -0,0 +1,67 @@ +/* + This file is part of Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qwidget.h> + +#include <kaboutdata.h> +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kparts/componentfactory.h> + +#include "core.h" +#include "plugin.h" + +#include "kitchensync_plugin.h" + +typedef KGenericFactory< KitchenSyncPlugin, Kontact::Core > KitchenSyncPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_kitchensync, + KitchenSyncPluginFactory( "kontact_kitchensync" ) ) + +KitchenSyncPlugin::KitchenSyncPlugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "KitchenSync" ) +{ + setInstance( KitchenSyncPluginFactory::instance() ); +} + +KitchenSyncPlugin::~KitchenSyncPlugin() +{ +} + +KParts::ReadOnlyPart* KitchenSyncPlugin::createPart() +{ + return loadPart(); +} + +QStringList KitchenSyncPlugin::configModules() const +{ + QStringList modules; + modules << "PIM/kitchensync.desktop"; + return modules; +} + +#include "kitchensync_plugin.moc" diff --git a/kontact/plugins/kitchensync/kitchensync_plugin.h b/kontact/plugins/kitchensync/kitchensync_plugin.h new file mode 100644 index 000000000..fafa12d71 --- /dev/null +++ b/kontact/plugins/kitchensync/kitchensync_plugin.h @@ -0,0 +1,51 @@ +/* + This file is part of Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KITCHENSYNC_PLUGIN_H +#define KITCHENSYNC_PLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include "plugin.h" + +class KAboutData; + +class KitchenSyncPlugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + KitchenSyncPlugin( Kontact::Core *core, const char *name, + const QStringList & ); + ~KitchenSyncPlugin(); + + int weight() const { return 800; } + + virtual QStringList configModules() const; + protected: + KParts::ReadOnlyPart *createPart(); +}; + +#endif diff --git a/kontact/plugins/kmail/Makefile.am b/kontact/plugins/kmail/Makefile.am new file mode 100644 index 000000000..d176693a3 --- /dev/null +++ b/kontact/plugins/kmail/Makefile.am @@ -0,0 +1,29 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir)/kmail -I$(top_builddir)/kmail \ + -I$(top_srcdir)/libkdepim \ + -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_kmailplugin.la kcm_kmailsummary.la + +libkontact_kmailplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_kmailplugin_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(top_builddir)/libkcal/libkcal.la $(LIB_KPARTS) + +libkontact_kmailplugin_la_SOURCES = kmail_plugin.cpp kmailIface.stub \ + summarywidget.cpp summarywidget.skel + +kcm_kmailsummary_la_SOURCES = kcmkmailsummary.cpp +kcm_kmailsummary_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) \ + -avoid-version -no-undefined +kcm_kmailsummary_la_LIBADD = $(LIB_KDEUI) + +kmailIface_DCOPIDLNG = true + +summarywidget_DCOPIDLNG = true + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = kmailplugin.desktop + +kde_services_DATA = kcmkmailsummary.desktop + +kmailIface_DIR = $(top_srcdir)/kmail diff --git a/kontact/plugins/kmail/kcmkmailsummary.cpp b/kontact/plugins/kmail/kcmkmailsummary.cpp new file mode 100644 index 000000000..02627c0fe --- /dev/null +++ b/kontact/plugins/kmail/kcmkmailsummary.cpp @@ -0,0 +1,192 @@ +/* + This file is part of Kontact. + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qcheckbox.h> +#include <qlayout.h> + +#include <dcopref.h> + +#include <kaboutdata.h> +#include <kaccelmanager.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialog.h> +#include <klistview.h> +#include <klocale.h> + +#include "kcmkmailsummary.h" + +#include <kdepimmacros.h> + +extern "C" +{ + KDE_EXPORT KCModule *create_kmailsummary( QWidget *parent, const char * ) + { + return new KCMKMailSummary( parent, "kcmkmailsummary" ); + } +} + +KCMKMailSummary::KCMKMailSummary( QWidget *parent, const char *name ) + : KCModule( parent, name ) +{ + initGUI(); + + connect( mFolderView, SIGNAL( clicked( QListViewItem* ) ), SLOT( modified() ) ); + connect( mFullPath, SIGNAL( toggled( bool ) ), SLOT( modified() ) ); + + KAcceleratorManager::manage( this ); + + load(); + + KAboutData *about = new KAboutData( I18N_NOOP( "kcmkmailsummary" ), + I18N_NOOP( "Mail Summary Configuration Dialog" ), + 0, 0, KAboutData::License_GPL, + I18N_NOOP( "(c) 2004 Tobias Koenig" ) ); + + about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" ); + setAboutData( about ); +} + +void KCMKMailSummary::modified() +{ + emit changed( true ); +} + +void KCMKMailSummary::initGUI() +{ + QVBoxLayout *layout = new QVBoxLayout( this, 0, KDialog::spacingHint() ); + + mFolderView = new KListView( this ); + mFolderView->setRootIsDecorated( true ); + mFolderView->setFullWidth( true ); + + mFolderView->addColumn( i18n( "Summary" ) ); + + mFullPath = new QCheckBox( i18n( "Show full path for folders" ), this ); + + layout->addWidget( mFolderView ); + layout->addWidget( mFullPath ); +} + +void KCMKMailSummary::initFolders() +{ + DCOPRef kmail( "kmail", "KMailIface" ); + + QStringList folderList; + kmail.call( "folderList" ).get( folderList ); + + mFolderView->clear(); + mFolderMap.clear(); + + QStringList::Iterator it; + for ( it = folderList.begin(); it != folderList.end(); ++it ) { + QString displayName; + if ( (*it) == "/Local" ) + displayName = i18n( "prefix for local folders", "Local" ); + else { + DCOPRef folderRef = kmail.call( "getFolder(QString)", *it ); + folderRef.call( "displayName()" ).get( displayName ); + } + if ( (*it).contains( '/' ) == 1 ) { + if ( mFolderMap.find( *it ) == mFolderMap.end() ) + mFolderMap.insert( *it, new QListViewItem( mFolderView, + displayName ) ); + } else { + const int pos = (*it).findRev( '/' ); + const QString parentFolder = (*it).left( pos ); + mFolderMap.insert( *it, + new QCheckListItem( mFolderMap[ parentFolder ], + displayName, + QCheckListItem::CheckBox ) ); + } + } +} + +void KCMKMailSummary::loadFolders() +{ + KConfig config( "kcmkmailsummaryrc" ); + config.setGroup( "General" ); + + QStringList folders; + if ( !config.hasKey( "ActiveFolders" ) ) + folders << "/Local/inbox"; + else + folders = config.readListEntry( "ActiveFolders" ); + + QMap<QString, QListViewItem*>::Iterator it; + for ( it = mFolderMap.begin(); it != mFolderMap.end(); ++it ) { + if ( QCheckListItem *qli = dynamic_cast<QCheckListItem*>( it.data() ) ) { + if ( folders.contains( it.key() ) ) { + qli->setOn( true ); + mFolderView->ensureItemVisible( it.data() ); + } else { + qli->setOn( false ); + } + } + } + mFullPath->setChecked( config.readBoolEntry( "ShowFullPath", true ) ); +} + +void KCMKMailSummary::storeFolders() +{ + KConfig config( "kcmkmailsummaryrc" ); + config.setGroup( "General" ); + + QStringList folders; + + QMap<QString, QListViewItem*>::Iterator it; + for ( it = mFolderMap.begin(); it != mFolderMap.end(); ++it ) + if ( QCheckListItem *qli = dynamic_cast<QCheckListItem*>( it.data() ) ) + if ( qli->isOn() ) + folders.append( it.key() ); + + config.writeEntry( "ActiveFolders", folders ); + config.writeEntry( "ShowFullPath", mFullPath->isChecked() ); + + config.sync(); +} + +void KCMKMailSummary::load() +{ + initFolders(); + loadFolders(); + + emit changed( false ); +} + +void KCMKMailSummary::save() +{ + storeFolders(); + + emit changed( false ); +} + +void KCMKMailSummary::defaults() +{ + mFullPath->setChecked( true ); + + emit changed( true ); +} + +#include "kcmkmailsummary.moc" diff --git a/kontact/plugins/kmail/kcmkmailsummary.desktop b/kontact/plugins/kmail/kcmkmailsummary.desktop new file mode 100644 index 000000000..2b8c7d99e --- /dev/null +++ b/kontact/plugins/kmail/kcmkmailsummary.desktop @@ -0,0 +1,107 @@ +[Desktop Entry] +Icon=kontact_mail +Type=Service +ServiceTypes=KCModule + +X-KDE-ModuleType=Library +X-KDE-Library=kmailsummary +X-KDE-FactoryName=kmailsummary +X-KDE-ParentApp=kontact_kmailplugin +X-KDE-ParentComponents=kontact_kmailplugin +X-KDE-CfgDlgHierarchy=KontactSummary + +Name=E-Mail Overview +Name[bg]=Преглед на пощата +Name[ca]=Resum de correu +Name[da]=Oversigt over e-mail +Name[de]=E-Mail-Übersicht +Name[el]=Επισκόπηση αλληλογραφίας +Name[es]=Resumen de correo electrónico +Name[et]=E-posti ülevaade +Name[fr]=Aperçu du courriel +Name[is]=Yfirsýn á tölvupóst +Name[it]=Panoramica posta elettronica +Name[ja]=メールの要約 +Name[km]=ទិដ្ឋភាពទូទៅរបស់អ៊ីមែល +Name[nds]=Nettpost-Översicht +Name[nl]=E-mailoverzicht +Name[pl]=Poczta +Name[ru]=Сведения о почте +Name[sk]=Prehľad pošty +Name[sr]=Преглед е-поште +Name[sr@Latn]=Pregled e-pošte +Name[sv]=E-postöversikt +Name[tr]=E-Postalara Genel Bakış +Name[zh_CN]=邮件概览 +Name[zh_TW]=郵件概要 +Comment=E-Mail Summary Setup +Comment[bg]=Настройки на обобщението на писмата +Comment[ca]=Configuració del resum de correu +Comment[da]=Opsætning af post-opsummering +Comment[de]=Einstellungen für E-Mail-Übersicht +Comment[el]=Ρύθμιση σύνοψης αλληλογραφίας +Comment[es]=Configuración del resumen de correo electrónico +Comment[et]=E-posti kokkuvõtte seadistus +Comment[fr]=Configuration du résumé des courriels +Comment[is]=Uppsetning póstyfirlits +Comment[it]=Impostazioni sommario posta elettronica +Comment[ja]=メール要約の設定 +Comment[km]=រៀបចំសេចក្ដីសង្ខេបអ៊ីមែល +Comment[nds]=Instellen för Nettpost-Översicht +Comment[nl]=Instellingen voor e-mailoverzicht +Comment[pl]=Ustawienia podsumowania e-maili +Comment[ru]=Настройка сводки почты +Comment[sk]=Nastavenie súhrnu pošty +Comment[sr]=Подешавање сажетка е-поште +Comment[sr@Latn]=Podešavanje sažetka e-pošte +Comment[sv]=Inställning av e-postöversikt +Comment[tr]=E-Posta Özet Yapılandırması +Comment[zh_CN]=邮件摘要设置 +Comment[zh_TW]=郵件摘要設定 +Keywords=email, summary, configure, settings +Keywords[af]=email,summary,configure,settings +Keywords[bg]=резюме, общо, обобщение, пощенски, клиент, е-поща, email, summary, configure, settings +Keywords[bs]=email, summary, configure, settings, sažetak, postavke +Keywords[ca]=correu-e, resum, configuració, arranjament +Keywords[cs]=email,souhrn,nastavení,nastavit +Keywords[da]=e-mail, opsummering, indstil, opsætning +Keywords[de]=E-Mail,email,Übersicht,einstellen,Einstellungen,Einrichten +Keywords[el]=αλληλογραφία, σύνοψη, ρύθμιση, ρυθμίσεις +Keywords[es]=correo, resumen, configurar, opciones +Keywords[et]=e-post, meil, seadistamine, seadistused +Keywords[eu]=eposta, laburpena, konfiguratu, ezarpenak +Keywords[fa]=email، خلاصه، پیکربندی، تنظیمات +Keywords[fi]=sähköposti, yhteenveto, asetukset +Keywords[fr]=message,messagerie,courriel,résumé,vue,configurer,paramètres,paramètre +Keywords[fy]=email,e-mail,e-post,oersicht,gearfetting,ynstellings, konfiguraasje +Keywords[ga]=ríomhphost, achoimre, cumraigh, socruithe +Keywords[gl]=email, resumo, configurar, opcións +Keywords[he]=email, summary, configure, settings, דוא"ל, תקציר, תצורה, הגדרת, דואל, דואר, דואר אלקטרוני +Keywords[hu]=e-mail,áttekintés,konfigurálás,beállítások +Keywords[is]=tölvupóstur, yfirlit, stillingar, stilla +Keywords[it]=posta elettronica, email, sommario, configura, impostazioni +Keywords[ja]=メール,要約,設定,設定 +Keywords[ka]=ელფოსტა,დაიჯესტი,კონფიგურაცია,პარამეტრები +Keywords[km]=អ៊ីមែល,សង្ខេប,កំណត់រចនាសម្ព័ន្ធ,ការកំណត់ +Keywords[lt]=email, summary, configure, settings, e. paštas, santrauka, konfigūruoti, nustatymai +Keywords[mk]=email, summary, configure, settings, е-пошта, преглед, конфигурација, поставувања +Keywords[ms]=e-mel, ringkasan, konfigur, seting +Keywords[nb]=e-post, sammendrag, oppsett, innstillinger +Keywords[nds]=Nettpost,Nettbreef,Översicht,instellen +Keywords[ne]=इमेल, सारांश, कन्फिगर, सेटिङ +Keywords[nl]=email,e-mail,overzicht,samenvatting,instellingen,configuratie +Keywords[nn]=e-post,samandrag,oppsett,innstillingar +Keywords[pl]=e-mail,list,podsumowanie,konfiguracja,ustawienia +Keywords[pt]=e-mail, sumário, configurar, configuração +Keywords[pt_BR]=e-mail, resumo, configurar, configurações +Keywords[ru]=email,summary,configure,settings,настройки,сводка,почта +Keywords[sk]=email,súhrn,nastavenie +Keywords[sl]=e-pošta,pošta,povzetek,nastavi,nastavitve +Keywords[sr]=емаил, сажетак, подеси, поставке +Keywords[sr@Latn]=email, sažetak, podesi, postavke +Keywords[sv]=e-post, översikt, anpassa, inställningar +Keywords[ta]=மின்னஞ்சல்,சுருக்கம்,கட்டமைப்பு,அமைவுகள் +Keywords[tg]=email, summary, configure, settings,танзимот, дайджест,почта +Keywords[tr]=e-posta, özet, yapılandır, yapılandırma +Keywords[uk]=пошта, підсумок, налаштування, параметри +Keywords[zh_CN]=email, summary, configure, settings, 电子邮件, 摘要, 配置, 设置 diff --git a/kontact/plugins/kmail/kcmkmailsummary.h b/kontact/plugins/kmail/kcmkmailsummary.h new file mode 100644 index 000000000..e2959dead --- /dev/null +++ b/kontact/plugins/kmail/kcmkmailsummary.h @@ -0,0 +1,61 @@ +/* + This file is part of Kontact. + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KCMKMAILSUMMARY_H +#define KCMKMAILSUMMARY_H + +#include <qvaluelist.h> + +#include <kcmodule.h> + +class KListView; + +class QCheckBox; +class QCheckListItem; + +class KCMKMailSummary : public KCModule +{ + Q_OBJECT + + public: + KCMKMailSummary( QWidget *parent = 0, const char *name = 0 ); + + virtual void load(); + virtual void save(); + virtual void defaults(); + + private slots: + void modified(); + + private: + void initGUI(); + void initFolders(); + void loadFolders(); + void storeFolders(); + + KListView *mFolderView; + QCheckBox *mFullPath; + QMap<QString, QListViewItem*> mFolderMap; +}; + +#endif diff --git a/kontact/plugins/kmail/kmail_plugin.cpp b/kontact/plugins/kmail/kmail_plugin.cpp new file mode 100644 index 000000000..3d9f45bec --- /dev/null +++ b/kontact/plugins/kmail/kmail_plugin.cpp @@ -0,0 +1,221 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Kontact Developer + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qwidget.h> + +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kparts/componentfactory.h> +#include <kstandarddirs.h> +#include <dcopclient.h> +#include <ktempfile.h> + +#include <kabc/addressee.h> + +#include <libkcal/vcaldrag.h> +#include <libkcal/icaldrag.h> +#include <libkcal/calendarlocal.h> + +#include <libkdepim/kvcarddrag.h> + +#include <kmail/kmail_part.h> +#include <kmail/kmkernel.h> + +#include "core.h" +#include "summarywidget.h" + +#include "kmail_plugin.h" + +using namespace KCal; + +typedef KGenericFactory<KMailPlugin, Kontact::Core> KMailPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_kmailplugin, + KMailPluginFactory( "kontact_kmailplugin" ) ) + +KMailPlugin::KMailPlugin(Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "kmail" ), + mStub( 0 ) +{ + setInstance( KMailPluginFactory::instance() ); + + insertNewAction( new KAction( i18n( "New Message..." ), "mail_new", + CTRL+SHIFT+Key_M, this, SLOT( slotNewMail() ), actionCollection(), + "new_mail" ) ); + + insertSyncAction( new KAction( i18n( "Synchronize Mail" ), "reload", + 0, this, SLOT( slotSyncFolders() ), actionCollection(), + "sync_mail" ) ); + + mUniqueAppWatcher = new Kontact::UniqueAppWatcher( + new Kontact::UniqueAppHandlerFactory<KMailUniqueAppHandler>(), this ); +} + +bool KMailPlugin::canDecodeDrag( QMimeSource *qms ) +{ + return ( ICalDrag::canDecode( qms ) || + VCalDrag::canDecode( qms ) || + KVCardDrag::canDecode( qms ) ); +} + +void KMailPlugin::processDropEvent( QDropEvent * de ) +{ + kdDebug() << k_funcinfo << endl; + CalendarLocal cal( QString::fromLatin1("UTC") ); + KABC::Addressee::List list; + + if ( VCalDrag::decode( de, &cal ) || ICalDrag::decode( de, &cal ) ) { + KTempFile tmp( locateLocal( "tmp", "incidences-" ), ".ics" ); + cal.save( tmp.name() ); + openComposer( KURL::fromPathOrURL( tmp.name() ) ); + } + else if ( KVCardDrag::decode( de, list ) ) { + KABC::Addressee::List::Iterator it; + QStringList to; + for ( it = list.begin(); it != list.end(); ++it ) { + to.append( ( *it ).fullEmail() ); + } + openComposer( to.join(", ") ); + } + +} + +void KMailPlugin::openComposer( const KURL& attach ) +{ + (void) part(); // ensure part is loaded + Q_ASSERT( mStub ); + if ( mStub ) { + if ( attach.isValid() ) + mStub->newMessage( "", "", "", false, true, KURL(), attach ); + else + mStub->newMessage( "", "", "", false, true, KURL(), KURL() ); + } +} + +void KMailPlugin::openComposer( const QString& to ) +{ + (void) part(); // ensure part is loaded + Q_ASSERT( mStub ); + if ( mStub ) { + mStub->newMessage( to, "", "", false, true, KURL(), KURL() ); + } +} + +void KMailPlugin::slotNewMail() +{ + openComposer( QString::null ); +} + +void KMailPlugin::slotSyncFolders() +{ + DCOPRef ref( "kmail", "KMailIface" ); + ref.send( "checkMail" ); +} + +KMailPlugin::~KMailPlugin() +{ +} + +bool KMailPlugin::createDCOPInterface( const QString& serviceType ) +{ + if ( serviceType == "DCOP/ResourceBackend/IMAP" ) { + if ( part() ) + return true; + } + + return false; +} + +QString KMailPlugin::tipFile() const +{ + QString file = ::locate("data", "kmail/tips"); + return file; +} + +KParts::ReadOnlyPart* KMailPlugin::createPart() +{ + KParts::ReadOnlyPart *part = loadPart(); + if ( !part ) return 0; + + mStub = new KMailIface_stub( dcopClient(), "kmail", "KMailIface" ); + + return part; +} + +QStringList KMailPlugin::invisibleToolbarActions() const +{ + return QStringList( "new_message" ); +} + +bool KMailPlugin::isRunningStandalone() +{ + return mUniqueAppWatcher->isRunningStandalone(); +} + +Kontact::Summary *KMailPlugin::createSummaryWidget( QWidget *parent ) +{ + return new SummaryWidget( this, parent ); +} + +//// + +#include "../../../kmail/kmail_options.h" +void KMailUniqueAppHandler::loadCommandLineOptions() +{ + KCmdLineArgs::addCmdLineOptions( kmail_options ); +} + +int KMailUniqueAppHandler::newInstance() +{ + // Ensure part is loaded + (void)plugin()->part(); + DCOPRef kmail( "kmail", "KMailIface" ); + DCOPReply reply = kmail.call( "handleCommandLine", false ); + if ( reply.isValid() ) { + bool handled = reply; + //kdDebug(5602) << k_funcinfo << "handled=" << handled << endl; + if ( !handled ) // no args -> simply bring kmail plugin to front + return Kontact::UniqueAppHandler::newInstance(); + } + return 0; +} + +bool KMailPlugin::queryClose() const { + KMailIface_stub stub( kapp->dcopClient(), "kmail", "KMailIface" ); + bool canClose=stub.canQueryClose(); + return canClose; +} + +void KMailPlugin::loadProfile( const QString& profileDirectory ) { + DCOPRef ref( "kmail", "KMailIface" ); + ref.send( "loadProfile", profileDirectory ); +} + +void KMailPlugin::saveToProfile( const QString& profileDirectory ) { + DCOPRef ref( "kmail", "KMailIface" ); + ref.send( "saveToProfile", profileDirectory ); +} + +#include "kmail_plugin.moc" diff --git a/kontact/plugins/kmail/kmail_plugin.h b/kontact/plugins/kmail/kmail_plugin.h new file mode 100644 index 000000000..0d6013867 --- /dev/null +++ b/kontact/plugins/kmail/kmail_plugin.h @@ -0,0 +1,86 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Kontact Developer + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KMAIL_PLUGIN_H +#define KMAIL_PLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include "kmailIface_stub.h" +#include <plugin.h> +#include <summary.h> +#include <uniqueapphandler.h> + +class QMimeSource; +class QDropEvent; + +class KMailUniqueAppHandler : public Kontact::UniqueAppHandler +{ +public: + KMailUniqueAppHandler( Kontact::Plugin* plugin ) : Kontact::UniqueAppHandler( plugin ) {} + virtual void loadCommandLineOptions(); + virtual int newInstance(); +}; + +class KMailPlugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + KMailPlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~KMailPlugin(); + + virtual bool isRunningStandalone(); + virtual bool createDCOPInterface( const QString& serviceType ); + virtual Kontact::Summary *createSummaryWidget( QWidget *parent ); + virtual QString tipFile() const; + int weight() const { return 200; } + + virtual QStringList invisibleToolbarActions() const; + virtual bool queryClose() const; + + //override + void loadProfile( const QString& profileDirectory ); + + //override + void saveToProfile( const QString& profileDirectory ); + + protected: + virtual KParts::ReadOnlyPart* createPart(); + void openComposer( const KURL& = KURL() ); + void openComposer( const QString& to ); + bool canDecodeDrag( QMimeSource * ); + void processDropEvent( QDropEvent * ); + + + protected slots: + void slotNewMail(); + void slotSyncFolders(); + + private: + KMailIface_stub *mStub; + Kontact::UniqueAppWatcher *mUniqueAppWatcher; +}; + +#endif diff --git a/kontact/plugins/kmail/kmailplugin.desktop b/kontact/plugins/kmail/kmailplugin.desktop new file mode 100644 index 000000000..55ba5e97b --- /dev/null +++ b/kontact/plugins/kmail/kmailplugin.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Type=Service +Icon=kontact_mail +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_kmailplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libkmailpart +X-KDE-KontactPartExecutableName=kmail +X-KDE-KontactPartLoadOnStart=true +X-KDE-KontactPluginHasSummary=true + +X-KDE-PluginInfo-Website=http://kmail.kde.org/ +X-KDE-PluginInfo-Name=kontact_kmailplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=E-Mail Component (KMail Plugin) +Comment[bg]=Модул за е-поща +Comment[ca]=Component de correu (endollable del KMail) +Comment[da]=Post-komponent (KMail-plugin) +Comment[de]=E-Mail-Komponente (KMail-Modul) +Comment[el]=Συστατικό αλληλογραφίας (Πρόσθετο του KMail) +Comment[es]=Componente de correo electrónico (complemento de KMail) +Comment[et]=E-posti plugin (KMail) +Comment[fr]=Composant de courriel (Module pour KMail) +Comment[is]=Pósteining (KMail íforrit) +Comment[it]=Componente posta elettronica (plugin KMail) +Comment[ja]=メールコンポーネント (KMail プラグイン) +Comment[km]=សមាសភាគអ៊ីមែល (កម្មវិធីជំនួយ KMail) +Comment[nds]=Nettpost-Komponent (KMail-Moduul) +Comment[nl]=E-mailcomponent (KMail-plugin) +Comment[pl]=Składnik poczty (wtyczka KMail) +Comment[pt_BR]=Componente de e-mail (plug-in do KMail) +Comment[ru]=Электронная почта (модуль KMail) +Comment[sk]=Poštový komponent (Model pre KMail) +Comment[sr]=Компонента е-поште (прикључак KMail-а) +Comment[sr@Latn]=Komponenta e-pošte (priključak KMail-a) +Comment[sv]=E-postkomponent (Kmail-insticksprogram) +Comment[tr]=E-Posta Bileşeni (KMail Eklentisi) +Comment[zh_CN]=邮件组件(KMail 插件) +Comment[zh_TW]=電子郵件組件(KMail 外掛程式) +Name=E-Mail +Name[bg]=Е-поща +Name[ca]=Correu +Name[da]=E-mail +Name[el]=Αλληλογραφία +Name[es]=Correo electrónico +Name[et]=E-post +Name[fr]=Courriel +Name[is]=Tölvupóstur +Name[it]=Posta elettronica +Name[ja]=メール +Name[km]=អ៊ីមែល +Name[nds]=Nettpost +Name[nl]=E-mail +Name[pl]=E-mail +Name[pt_BR]=E-mail +Name[ru]=Электронная почта +Name[sk]=Pošta +Name[sr]=Е-пошта +Name[sr@Latn]=E-pošta +Name[sv]=E-post +Name[tr]=E-Posta +Name[zh_CN]=邮件 +Name[zh_TW]=電子郵件 diff --git a/kontact/plugins/kmail/summarywidget.cpp b/kontact/plugins/kmail/summarywidget.cpp new file mode 100644 index 000000000..79f2f4657 --- /dev/null +++ b/kontact/plugins/kmail/summarywidget.cpp @@ -0,0 +1,182 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qlabel.h> +#include <qlayout.h> + +#include <dcopref.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kparts/part.h> + +#include "core.h" +#include "summary.h" +#include "summarywidget.h" + +#include <time.h> + +SummaryWidget::SummaryWidget( Kontact::Plugin *plugin, QWidget *parent, const char *name ) + : Kontact::Summary( parent, name ), + DCOPObject( QCString("MailSummary") ), + mPlugin( plugin ) +{ + QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 ); + + QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_mail", KIcon::Desktop, + KIcon::SizeMedium ); + QWidget *header = createHeader(this, icon, i18n("E-Mail")); + mLayout = new QGridLayout( 1, 3, 3 ); + + mainLayout->addWidget(header); + mainLayout->addLayout(mLayout); + + slotUnreadCountChanged(); + connectDCOPSignal( 0, 0, "unreadCountChanged()", "slotUnreadCountChanged()", + false ); +} + +void SummaryWidget::selectFolder( const QString& folder ) +{ + if ( mPlugin->isRunningStandalone() ) + mPlugin->bringToForeground(); + else + mPlugin->core()->selectPlugin( mPlugin ); + QByteArray data; + QDataStream arg( data, IO_WriteOnly ); + arg << folder; + emitDCOPSignal( "kmailSelectFolder(QString)", data ); +} + +void SummaryWidget::updateSummary( bool ) +{ + // check whether we need to update the message counts + DCOPRef kmail( "kmail", "KMailIface" ); + const int timeOfLastMessageCountChange = + kmail.call( "timeOfLastMessageCountChange()" ); + if ( timeOfLastMessageCountChange > mTimeOfLastMessageCountUpdate ) + slotUnreadCountChanged(); +} + +void SummaryWidget::slotUnreadCountChanged() +{ + DCOPRef kmail( "kmail", "KMailIface" ); + DCOPReply reply = kmail.call( "folderList" ); + if ( reply.isValid() ) { + QStringList folderList = reply; + updateFolderList( folderList ); + } + else { + kdDebug(5602) << "Calling kmail->KMailIface->folderList() via DCOP failed." + << endl; + } + mTimeOfLastMessageCountUpdate = ::time( 0 ); +} + +void SummaryWidget::updateFolderList( const QStringList& folders ) +{ + mLabels.setAutoDelete( true ); + mLabels.clear(); + mLabels.setAutoDelete( false ); + + KConfig config( "kcmkmailsummaryrc" ); + config.setGroup( "General" ); + + QStringList activeFolders; + if ( !config.hasKey( "ActiveFolders" ) ) + activeFolders << "/Local/inbox"; + else + activeFolders = config.readListEntry( "ActiveFolders" ); + + int counter = 0; + QStringList::ConstIterator it; + DCOPRef kmail( "kmail", "KMailIface" ); + for ( it = folders.begin(); it != folders.end(); ++it ) { + if ( activeFolders.contains( *it ) ) { + DCOPRef folderRef = kmail.call( "getFolder(QString)", *it ); + const int numMsg = folderRef.call( "messages()" ); + const int numUnreadMsg = folderRef.call( "unreadMessages()" ); + + if ( numUnreadMsg == 0 ) continue; + + QString folderPath; + if ( config.readBoolEntry( "ShowFullPath", true ) ) + folderRef.call( "displayPath()" ).get( folderPath ); + else + folderRef.call( "displayName()" ).get( folderPath ); + + KURLLabel *urlLabel = new KURLLabel( *it, folderPath, this ); + urlLabel->installEventFilter( this ); + urlLabel->setAlignment( AlignLeft ); + urlLabel->show(); + connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + SLOT( selectFolder( const QString& ) ) ); + mLayout->addWidget( urlLabel, counter, 0 ); + mLabels.append( urlLabel ); + + QLabel *label = + new QLabel( QString( i18n("%1: number of unread messages " + "%2: total number of messages", "%1 / %2") ) + .arg( numUnreadMsg ).arg( numMsg ), this ); + label->setAlignment( AlignLeft ); + label->show(); + mLayout->addWidget( label, counter, 2 ); + mLabels.append( label ); + + counter++; + } + } + + if ( counter == 0 ) { + QLabel *label = new QLabel( i18n( "No unread messages in your monitored folders" ), this ); + label->setAlignment( AlignHCenter | AlignVCenter ); + mLayout->addMultiCellWidget( label, 0, 0, 0, 2 ); + label->show(); + mLabels.append( label ); + } +} + +bool SummaryWidget::eventFilter( QObject *obj, QEvent* e ) +{ + if ( obj->inherits( "KURLLabel" ) ) { + KURLLabel* label = static_cast<KURLLabel*>( obj ); + if ( e->type() == QEvent::Enter ) + emit message( i18n( "Open Folder: \"%1\"" ).arg( label->text() ) ); + if ( e->type() == QEvent::Leave ) + emit message( QString::null ); + } + + return Kontact::Summary::eventFilter( obj, e ); +} + +QStringList SummaryWidget::configModules() const +{ + return QStringList( "kcmkmailsummary.desktop" ); +} + +#include "summarywidget.moc" diff --git a/kontact/plugins/kmail/summarywidget.h b/kontact/plugins/kmail/summarywidget.h new file mode 100644 index 000000000..563a021e1 --- /dev/null +++ b/kontact/plugins/kmail/summarywidget.h @@ -0,0 +1,73 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SUMMARYWIDGET_H +#define SUMMARYWIDGET_H + +#include <qmap.h> +#include <qtimer.h> +#include <qwidget.h> + +#include <dcopobject.h> +#include <kurllabel.h> +#include <kparts/part.h> + +#include "plugin.h" +#include "summary.h" + +class QGridLayout; +class QString; + +class SummaryWidget : public Kontact::Summary, public DCOPObject +{ + Q_OBJECT + K_DCOP + + public: + SummaryWidget( Kontact::Plugin *plugin, QWidget *parent, const char *name = 0 ); + + int summaryHeight() const { return 1; } + QStringList configModules() const; + + k_dcop_hidden: + void slotUnreadCountChanged(); + + protected: + virtual bool eventFilter( QObject *obj, QEvent* e ); + + public slots: + virtual void updateSummary( bool force ); + + private slots: + void selectFolder( const QString& ); + + private: + void updateFolderList( const QStringList& folders ); + + QPtrList<QLabel> mLabels; + QGridLayout *mLayout; + Kontact::Plugin *mPlugin; + int mTimeOfLastMessageCountUpdate; +}; + +#endif diff --git a/kontact/plugins/knode/Makefile.am b/kontact/plugins/knode/Makefile.am new file mode 100644 index 000000000..bf4ba753a --- /dev/null +++ b/kontact/plugins/knode/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir)/knode -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_knodeplugin.la +libkontact_knodeplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_knodeplugin_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) + +libkontact_knodeplugin_la_SOURCES = knode_plugin.cpp knodeiface.stub + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = knodeplugin.desktop + +knodeiface_DIR = $(top_srcdir)/knode diff --git a/kontact/plugins/knode/knode_plugin.cpp b/kontact/plugins/knode/knode_plugin.cpp new file mode 100644 index 000000000..6ad7fedb1 --- /dev/null +++ b/kontact/plugins/knode/knode_plugin.cpp @@ -0,0 +1,123 @@ +/* + This file is part of Kontact. + + Copyright (c) 2003 Zack Rusin <zack@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include "knode_plugin.h" + +#include "core.h" + +#include <kapplication.h> +#include <kparts/componentfactory.h> +#include <kgenericfactory.h> +#include <kapplication.h> +#include <kaction.h> +#include <kiconloader.h> +#include <kdebug.h> + +#include <dcopclient.h> + +#include <qwidget.h> + + +typedef KGenericFactory<KNodePlugin, Kontact::Core> KNodePluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_knodeplugin, + KNodePluginFactory( "kontact_knodeplugin" ) ) + + +KNodePlugin::KNodePlugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "knode" ), mStub(0) +{ + setInstance( KNodePluginFactory::instance() ); + + insertNewAction( new KAction( i18n( "New Article..." ), "mail_new", CTRL+SHIFT+Key_A, + this, SLOT( slotPostArticle() ), actionCollection(), "post_article" ) ); + + mUniqueAppWatcher = new Kontact::UniqueAppWatcher( + new Kontact::UniqueAppHandlerFactory<KNodeUniqueAppHandler>(), this ); +} + +KNodePlugin::~KNodePlugin() +{ +} + +bool KNodePlugin::createDCOPInterface( const QString& /*serviceType*/ ) +{ + return false; +} + +bool KNodePlugin::isRunningStandalone() +{ + return mUniqueAppWatcher->isRunningStandalone(); +} + +QStringList KNodePlugin::invisibleToolbarActions() const +{ + return QStringList( "article_postNew" ); +} + +void KNodePlugin::slotPostArticle() +{ + (void) part(); // ensure part is loaded + Q_ASSERT( mStub ); + if ( mStub ) + mStub->postArticle(); +} + +KParts::ReadOnlyPart* KNodePlugin::createPart() +{ + KParts::ReadOnlyPart *part = loadPart(); + if ( !part ) return 0; + + mStub = new KNodeIface_stub( dcopClient(), "knode", "KNodeIface" ); + return part; +} + +//// + +#include "../../../knode/knode_options.h" +void KNodeUniqueAppHandler::loadCommandLineOptions() +{ + KCmdLineArgs::addCmdLineOptions( knode_options ); +} + +int KNodeUniqueAppHandler::newInstance() +{ + // Ensure part is loaded + (void)plugin()->part(); + DCOPRef knode( "knode", "KNodeIface" ); + DCOPReply reply = knode.call( "handleCommandLine" ); +#if 0 + if ( reply.isValid() ) { + bool handled = reply; + kdDebug(5602) << k_funcinfo << "handled=" << handled << endl; + if ( !handled ) +#endif + // in all cases, bring knode plugin to front + return Kontact::UniqueAppHandler::newInstance(); +#if 0 + } + return 0; +#endif +} + +#include "knode_plugin.moc" diff --git a/kontact/plugins/knode/knode_plugin.h b/kontact/plugins/knode/knode_plugin.h new file mode 100644 index 000000000..78d4275ed --- /dev/null +++ b/kontact/plugins/knode/knode_plugin.h @@ -0,0 +1,68 @@ +/* + This file is part of Kontact. + + Copyright (c) 2003 Zack Rusin <zack@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KNODE_PLUGIN_H +#define KNODE_PLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include "knodeiface_stub.h" +#include "plugin.h" +#include <uniqueapphandler.h> + +class KNodeUniqueAppHandler : public Kontact::UniqueAppHandler +{ +public: + KNodeUniqueAppHandler( Kontact::Plugin* plugin ) : Kontact::UniqueAppHandler( plugin ) {} + virtual void loadCommandLineOptions(); + virtual int newInstance(); +}; + +class KNodePlugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + KNodePlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~KNodePlugin(); + + virtual bool createDCOPInterface( const QString& serviceType ); + virtual bool isRunningStandalone(); + int weight() const { return 500; } + + virtual QStringList invisibleToolbarActions() const; + + protected: + virtual KParts::ReadOnlyPart* createPart(); + + protected slots: + void slotPostArticle(); + + private: + KNodeIface_stub *mStub; + Kontact::UniqueAppWatcher *mUniqueAppWatcher; +}; + +#endif diff --git a/kontact/plugins/knode/knodeplugin.desktop b/kontact/plugins/knode/knodeplugin.desktop new file mode 100644 index 000000000..d84c16f7e --- /dev/null +++ b/kontact/plugins/knode/knodeplugin.desktop @@ -0,0 +1,98 @@ +[Desktop Entry] +Type=Service +Icon=kontact_news +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_knodeplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libknodepart +X-KDE-KontactPartExecutableName=knode + +X-KDE-PluginInfo-Name=kontact_knodeplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=false + +Comment=Newsreader Component (KNode Plugin) +Comment[bg]=Приставка за KNode +Comment[ca]=Component de notícies (endollable del KNode) +Comment[da]=Nyhedskomponent (KNode-plugin) +Comment[de]=News-Komponente (KNode-Modul) +Comment[el]=Συστατικό ανάγνωσης νέων (Πρόσθετο του KNode) +Comment[es]=Componente de noticias (complemento de KNode) +Comment[et]=Uudistelugeja plugin (KNode) +Comment[fr]=Composant de lecteur de nouvelles (Module pour KNode) +Comment[is]=Fréttaeining (KNode íforrit) +Comment[it]=Componente lettore di news (plugin KNode) +Comment[ja]=ニュースリーダーコンポーネント (KNode プラグイン) +Comment[km]=សមាសភាគ Newsreader (កម្មវិធីជំនួយ KNode) +Comment[nds]=Narichtenkieker-Komponent (KNode-Moduul) +Comment[nl]=Nieuwscomponent (KNode-plugin) +Comment[pl]=Składnik wiadomości (wtyczka KNode) +Comment[ru]=Новости (модуль KNode) +Comment[sr]=Компонента вести (прикључак KNode-а) +Comment[sr@Latn]=Komponenta vesti (priključak KNode-a) +Comment[sv]=Komponent för läsning av diskussionsgrupper (Knode-insticksprogram) +Comment[tr]=Haber Okuyucu Bileşeni (KNode Eklentisi) +Comment[zh_CN]=新闻组阅读器组件(KNode 插件) +Comment[zh_TW]=新聞閱讀器組件(KNode 外掛程式) +Name=News +Name[af]=Nuus +Name[ar]=الأخبار +Name[be]=Навіны +Name[bg]=Новини +Name[br]=Keleier +Name[bs]=Usenet +Name[ca]=Notícies +Name[cs]=Novinky +Name[cy]=Newyddion +Name[da]=Nyheder +Name[de]=Usenet +Name[el]=Νέα +Name[eo]=Novaĵoj +Name[es]=Noticias +Name[et]=Uudisegrupid +Name[eu]=Berriak +Name[fa]=اخبار +Name[fi]=Uutiset +Name[fr]=Nouvelles +Name[fy]=Nijs +Name[ga]=Nuacht +Name[gl]=Novas +Name[he]=חדשות +Name[hi]=समाचार +Name[hu]=Hírek +Name[is]=Fréttir +Name[ja]=ニュース +Name[ka]=სიახლეები +Name[kk]=Жаңалықтар +Name[km]=ព័ត៌មាន +Name[lt]=Naujienos +Name[mk]=Вести +Name[ms]=Berita +Name[nb]=Njus +Name[nds]=Narichten +Name[ne]=समाचार +Name[nl]=Nieuws +Name[nn]=Nyheiter +Name[pa]=ਖ਼ਬਰਾਂ +Name[pl]=Listy dyskusyjne +Name[pt]=Notícias +Name[pt_BR]=Notícias +Name[ro]=Ştiri +Name[ru]=Новости +Name[se]=Ođđasat +Name[sk]=Diskusné skupiny +Name[sl]=Novice +Name[sr]=Вести +Name[sr@Latn]=Vesti +Name[sv]=Nyheter +Name[ta]=செய்திகள் +Name[tg]=Ахборот +Name[th]=ข่าว +Name[tr]=Haberler +Name[uk]=Новини +Name[uz]=Yangiliklar +Name[uz@cyrillic]=Янгиликлар +Name[zh_CN]=新闻 +Name[zh_TW]=新聞 diff --git a/kontact/plugins/knotes/Makefile.am b/kontact/plugins/knotes/Makefile.am new file mode 100644 index 000000000..4a3b1710f --- /dev/null +++ b/kontact/plugins/knotes/Makefile.am @@ -0,0 +1,23 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_knotesplugin.la +libkontact_knotesplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_knotesplugin_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la \ + $(LIB_KPARTS) $(top_builddir)/libkdepim/libkdepim.la \ + $(top_builddir)/libkcal/libkcal.la -lkresources -lkdeprint \ + $(top_builddir)/knotes/libknotesresources.la \ + $(top_builddir)/knotes/libknoteseditor.la \ + $(top_builddir)/knotes/libknotesprinting.la + +libkontact_knotesplugin_la_SOURCES = knotes_plugin.cpp knotes_part.cpp summarywidget.cpp \ + knotetip.cpp KNotesIface.skel + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = knotesplugin.desktop + +partdir = $(kde_datadir)/knotes +part_DATA = knotes_part.rc + +KNotesIface_DIR = $(top_srcdir)/knotes diff --git a/kontact/plugins/knotes/knotes_part.cpp b/kontact/plugins/knotes/knotes_part.cpp new file mode 100644 index 000000000..5bd160d1d --- /dev/null +++ b/kontact/plugins/knotes/knotes_part.cpp @@ -0,0 +1,413 @@ +/* + This file is part of the KDE project + Copyright (C) 2002-2003 Daniel Molkentin <molkentin@kde.org> + Copyright (C) 2004-2006 Michael Brade <brade@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qpopupmenu.h> +#include <qclipboard.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kaction.h> +#include <kmessagebox.h> + +#include <libkdepim/infoextension.h> +#include <libkdepim/sidebarextension.h> + +#include "knotes/knoteprinter.h" +#include "knotes/resourcemanager.h" + +#include "knotes_part.h" +#include "knotes_part_p.h" +#include "knotetip.h" + + +KNotesPart::KNotesPart( QObject *parent, const char *name ) + : DCOPObject( "KNotesIface" ), KParts::ReadOnlyPart( parent, name ), + mNotesView( new KNotesIconView() ), + mNoteTip( new KNoteTip( mNotesView ) ), + mNoteEditDlg( 0 ), + mManager( new KNotesResourceManager() ) +{ + mNoteList.setAutoDelete( true ); + + setInstance( new KInstance( "knotes" ) ); + + // create the actions + new KAction( i18n( "&New" ), "knotes", CTRL+Key_N, this, SLOT( newNote() ), + actionCollection(), "file_new" ); + new KAction( i18n( "Rename..." ), "text", this, SLOT( renameNote() ), + actionCollection(), "edit_rename" ); + new KAction( i18n( "Delete" ), "editdelete", Key_Delete, this, SLOT( killSelectedNotes() ), + actionCollection(), "edit_delete" ); + new KAction( i18n( "Print Selected Notes..." ), "print", CTRL+Key_P, this, SLOT( printSelectedNotes() ), + actionCollection(), "print_note" ); + + // TODO icons: s/editdelete/knotes_delete/ or the other way round in knotes + + // set the view up + mNotesView->setSelectionMode( QIconView::Extended ); + mNotesView->setItemsMovable( false ); + mNotesView->setResizeMode( QIconView::Adjust ); + mNotesView->setAutoArrange( true ); + mNotesView->setSorting( true ); + + connect( mNotesView, SIGNAL( executed( QIconViewItem* ) ), + this, SLOT( editNote( QIconViewItem* ) ) ); + connect( mNotesView, SIGNAL( returnPressed( QIconViewItem* ) ), + this, SLOT( editNote( QIconViewItem* ) ) ); + connect( mNotesView, SIGNAL( itemRenamed( QIconViewItem* ) ), + this, SLOT( renamedNote( QIconViewItem* ) ) ); + connect( mNotesView, SIGNAL( contextMenuRequested( QIconViewItem*, const QPoint& ) ), + this, SLOT( popupRMB( QIconViewItem*, const QPoint& ) ) ); + connect( mNotesView, SIGNAL( onItem( QIconViewItem* ) ), + this, SLOT( slotOnItem( QIconViewItem* ) ) ); + connect( mNotesView, SIGNAL( onViewport() ), + this, SLOT( slotOnViewport() ) ); + connect( mNotesView, SIGNAL( currentChanged( QIconViewItem* ) ), + this, SLOT( slotOnCurrentChanged( QIconViewItem* ) ) ); + + slotOnCurrentChanged( 0 ); + + new KParts::SideBarExtension( mNotesView, this, "NotesSideBarExtension" ); + + setWidget( mNotesView ); + setXMLFile( "knotes_part.rc" ); + + // connect the resource manager + connect( mManager, SIGNAL( sigRegisteredNote( KCal::Journal* ) ), + this, SLOT( createNote( KCal::Journal* ) ) ); + connect( mManager, SIGNAL( sigDeregisteredNote( KCal::Journal* ) ), + this, SLOT( killNote( KCal::Journal* ) ) ); + + // read the notes + mManager->load(); +} + +KNotesPart::~KNotesPart() +{ + delete mNoteTip; + mNoteTip = 0; + + delete mManager; + mManager = 0; +} + +void KNotesPart::printSelectedNotes() +{ + QValueList<KCal::Journal*> journals; + + for ( QIconViewItem *it = mNotesView->firstItem(); it; it = it->nextItem() ) { + if ( it->isSelected() ) { + journals.append( static_cast<KNotesIconViewItem *>( it )->journal() ); + } + } + + if ( journals.isEmpty() ) { + KMessageBox::information( mNotesView, i18n("To print notes, first select the notes to print from the list."), i18n("Print Notes") ); + return; + } + + KNotePrinter printer; + printer.printNotes(journals ); + +#if 0 + QString content; + if ( m_editor->textFormat() == PlainText ) + content = QStyleSheet::convertFromPlainText( m_editor->text() ); + else + content = m_editor->text(); + + KNotePrinter printer; + printer.setMimeSourceFactory( m_editor->mimeSourceFactory() ); + //printer.setFont( m_config->font() ); + //printer.setContext( m_editor->context() ); + //printer.setStyleSheet( m_editor->styleSheet() ); + printer.setColorGroup( colorGroup() ); + printer.printNote( , content ); +#endif +} + +bool KNotesPart::openFile() +{ + return false; +} + + +// public KNotes DCOP interface implementation + +QString KNotesPart::newNote( const QString& name, const QString& text ) +{ + // create the new note + KCal::Journal *journal = new KCal::Journal(); + + // new notes have the current date/time as title if none was given + if ( !name.isEmpty() ) + journal->setSummary( name ); + else + journal->setSummary( KGlobal::locale()->formatDateTime( QDateTime::currentDateTime() ) ); + + // the body of the note + journal->setDescription( text ); + + + + // Edit the new note if text is empty + if ( text.isNull() ) + { + if ( !mNoteEditDlg ) + mNoteEditDlg = new KNoteEditDlg( widget() ); + + mNoteEditDlg->setTitle( journal->summary() ); + mNoteEditDlg->setText( journal->description() ); + + if ( mNoteEditDlg->exec() == QDialog::Accepted ) + { + journal->setSummary( mNoteEditDlg->title() ); + journal->setDescription( mNoteEditDlg->text() ); + } + else + { + delete journal; + return ""; + } + } + + mManager->addNewNote( journal ); + mManager->save(); + + KNotesIconViewItem *note = mNoteList[ journal->uid() ]; + mNotesView->ensureItemVisible( note ); + mNotesView->setCurrentItem( note ); + + return journal->uid(); +} + +QString KNotesPart::newNoteFromClipboard( const QString& name ) +{ + const QString& text = KApplication::clipboard()->text(); + return newNote( name, text ); +} + +void KNotesPart::killNote( const QString& id ) +{ + killNote( id, false ); +} + +void KNotesPart::killNote( const QString& id, bool force ) +{ + KNotesIconViewItem *note = mNoteList[ id ]; + + if ( note && + ( (!force && KMessageBox::warningContinueCancelList( mNotesView, + i18n( "Do you really want to delete this note?" ), + mNoteList[ id ]->text(), i18n( "Confirm Delete" ), + KStdGuiItem::del() ) == KMessageBox::Continue) + || force ) + ) + { + mManager->deleteNote( mNoteList[id]->journal() ); + mManager->save(); + } +} + +QString KNotesPart::name( const QString& id ) const +{ + KNotesIconViewItem *note = mNoteList[ id ]; + if ( note ) + return note->text(); + else + return QString::null; +} + +QString KNotesPart::text( const QString& id ) const +{ + KNotesIconViewItem *note = mNoteList[id]; + if ( note ) + return note->journal()->description(); + else + return QString::null; +} + +void KNotesPart::setName( const QString& id, const QString& newName ) +{ + KNotesIconViewItem *note = mNoteList[ id ]; + if ( note ) { + note->setText( newName ); + mManager->save(); + } +} + +void KNotesPart::setText( const QString& id, const QString& newText ) +{ + KNotesIconViewItem *note = mNoteList[ id ]; + if ( note ) { + note->journal()->setDescription( newText ); + mManager->save(); + } +} + +QMap<QString, QString> KNotesPart::notes() const +{ + QMap<QString, QString> notes; + QDictIterator<KNotesIconViewItem> it( mNoteList ); + + for ( ; it.current(); ++it ) + notes.insert( (*it)->journal()->uid(), (*it)->journal()->summary() ); + + return notes; +} + + +// private stuff + +void KNotesPart::killSelectedNotes() +{ + QPtrList<KNotesIconViewItem> items; + QStringList notes; + + KNotesIconViewItem *knivi; + for ( QIconViewItem *it = mNotesView->firstItem(); it; it = it->nextItem() ) { + if ( it->isSelected() ) { + knivi = static_cast<KNotesIconViewItem *>( it ); + items.append( knivi ); + notes.append( knivi->text() ); + } + } + + if ( items.isEmpty() ) + return; + + int ret = KMessageBox::warningContinueCancelList( mNotesView, + i18n( "Do you really want to delete this note?", + "Do you really want to delete these %n notes?", items.count() ), + notes, i18n( "Confirm Delete" ), + KStdGuiItem::del() ); + + if ( ret == KMessageBox::Continue ) { + QPtrListIterator<KNotesIconViewItem> kniviIt( items ); + while ( (knivi = *kniviIt) ) { + ++kniviIt; + mManager->deleteNote( knivi->journal() ); + } + + mManager->save(); + } +} + +void KNotesPart::popupRMB( QIconViewItem *item, const QPoint& pos ) +{ + QPopupMenu *contextMenu = NULL; + + if ( item ) + contextMenu = static_cast<QPopupMenu *>( factory()->container( "note_context", this ) ); + else + contextMenu = static_cast<QPopupMenu *>( factory()->container( "notepart_context", this ) ); + + if ( !contextMenu ) + return; + + contextMenu->popup( pos ); +} + +void KNotesPart::slotOnItem( QIconViewItem *i ) +{ + // TODO: disable (i.e. setNote( QString::null )) when mouse button pressed + + KNotesIconViewItem *item = static_cast<KNotesIconViewItem *>( i ); + mNoteTip->setNote( item ); +} + +void KNotesPart::slotOnViewport() +{ + mNoteTip->setNote( 0 ); +} + +// TODO: also with takeItem, clear(), + +// create and kill the icon view item corresponding to the note, edit the note + +void KNotesPart::createNote( KCal::Journal *journal ) +{ + // make sure all fields are existent, initialize them with default values + QString property = journal->customProperty( "KNotes", "BgColor" ); + if ( property.isNull() ) + journal->setCustomProperty( "KNotes", "BgColor", "#ffff00" ); + + property = journal->customProperty( "KNotes", "FgColor" ); + if ( property.isNull() ) + journal->setCustomProperty( "KNotes", "FgColor", "#000000" ); + + property = journal->customProperty( "KNotes", "RichText" ); + if ( property.isNull() ) + journal->setCustomProperty( "KNotes", "RichText", "true" ); + + mNoteList.insert( journal->uid(), new KNotesIconViewItem( mNotesView, journal ) ); +} + +void KNotesPart::killNote( KCal::Journal *journal ) +{ + mNoteList.remove( journal->uid() ); +} + +void KNotesPart::editNote( QIconViewItem *item ) +{ + if ( !mNoteEditDlg ) + mNoteEditDlg = new KNoteEditDlg( widget() ); + + KCal::Journal *journal = static_cast<KNotesIconViewItem *>( item )->journal(); + + mNoteEditDlg->setRichText( journal->customProperty( "KNotes", "RichText" ) == "true" ); + mNoteEditDlg->setTitle( journal->summary() ); + mNoteEditDlg->setText( journal->description() ); + + if ( mNoteEditDlg->exec() == QDialog::Accepted ) { + item->setText( mNoteEditDlg->title() ); + journal->setDescription( mNoteEditDlg->text() ); + mManager->save(); + } +} + +void KNotesPart::renameNote() +{ + mNotesView->currentItem()->rename(); +} + +void KNotesPart::renamedNote( QIconViewItem* ) +{ + mManager->save(); +} + +void KNotesPart::slotOnCurrentChanged( QIconViewItem* ) +{ + KAction *renameAction = actionCollection()->action( "edit_rename" ); + KAction *deleteAction = actionCollection()->action( "edit_delete" ); + + if ( !mNotesView->currentItem() ) { + renameAction->setEnabled( false ); + deleteAction->setEnabled( false ); + } else { + renameAction->setEnabled( true ); + deleteAction->setEnabled( true ); + } +} + +#include "knotes_part.moc" +#include "knotes_part_p.moc" + diff --git a/kontact/plugins/knotes/knotes_part.h b/kontact/plugins/knotes/knotes_part.h new file mode 100644 index 000000000..c034d04fb --- /dev/null +++ b/kontact/plugins/knotes/knotes_part.h @@ -0,0 +1,101 @@ +/* + This file is part of the KDE project + Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org> + Copyright (C) 2004-2006 Michael Brade <brade@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KNOTES_PART_H +#define KNOTES_PART_H + +#include <qdict.h> + +#include <kiconview.h> +#include <kglobal.h> +#include <kiconloader.h> + +#include <libkcal/journal.h> +#include <kparts/part.h> + +#include "knotes/KNotesIface.h" + +class KIconView; +class QIconViewItem; +class KNotesIconViewItem; +class KNoteTip; +class KNoteEditDlg; +class KNotesResourceManager; + +namespace KCal { +class Journal; +} + +class KNotesPart : public KParts::ReadOnlyPart, virtual public KNotesIface +{ + Q_OBJECT + + public: + KNotesPart( QObject *parent = 0, const char *name = 0 ); + ~KNotesPart(); + + bool openFile(); + + public slots: + QString newNote( const QString& name = QString::null, + const QString& text = QString::null ); + QString newNoteFromClipboard( const QString& name = QString::null ); + + public: + void killNote( const QString& id ); + void killNote( const QString& id, bool force ); + + QString name( const QString& id ) const; + QString text( const QString& id ) const; + + void setName( const QString& id, const QString& newName ); + void setText( const QString& id, const QString& newText ); + + QMap<QString, QString> notes() const; + + private slots: + void createNote( KCal::Journal *journal ); + void killNote( KCal::Journal *journal ); + + void editNote( QIconViewItem *item ); + + void renameNote(); + void renamedNote( QIconViewItem *item ); + + void slotOnItem( QIconViewItem *item ); + void slotOnViewport(); + void slotOnCurrentChanged( QIconViewItem *item ); + + void popupRMB( QIconViewItem *item, const QPoint& pos ); + void killSelectedNotes(); + + void printSelectedNotes(); + + private: + KIconView *mNotesView; + KNoteTip *mNoteTip; + KNoteEditDlg *mNoteEditDlg; + + KNotesResourceManager *mManager; + QDict<KNotesIconViewItem> mNoteList; +}; + +#endif diff --git a/kontact/plugins/knotes/knotes_part.rc b/kontact/plugins/knotes/knotes_part.rc new file mode 100644 index 000000000..ef4461868 --- /dev/null +++ b/kontact/plugins/knotes/knotes_part.rc @@ -0,0 +1,23 @@ +<!DOCTYPE kpartgui> +<kpartgui name="knotes" version="5"> + <MenuBar> + <Menu name="file"><text>&File</text> + <Merge/> + <Action name="print_note"/> + </Menu> + <Menu name="edit"><text>&Edit</text> + <Action name="edit_rename"/> + <Action name="edit_delete"/> + </Menu> + </MenuBar> + <Menu name="note_context"> + <Action name="file_new"/> + <Action name="edit_rename"/> + <Action name="edit_delete"/> + <Action name="print_note"/> + </Menu> + <Menu name="notepart_context"> + <Action name="file_new"/> + </Menu> + +</kpartgui> diff --git a/kontact/plugins/knotes/knotes_part_p.h b/kontact/plugins/knotes/knotes_part_p.h new file mode 100644 index 000000000..55a0374b6 --- /dev/null +++ b/kontact/plugins/knotes/knotes_part_p.h @@ -0,0 +1,188 @@ +/* + This file is part of the KDE project + Copyright (C) 2004-2006 Michael Brade <brade@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef KNOTES_PART_P_H +#define KNOTES_PART_P_H + +#include <qlayout.h> +#include <qlabel.h> + +#include <kactioncollection.h> +#include <klocale.h> +#include <kiconview.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kiconeffect.h> +#include <klineedit.h> +#include <ktoolbar.h> +#include <kpopupmenu.h> +#include <kdialogbase.h> +#include <kxmlguiclient.h> +#include <kxmlguifactory.h> +#include <kxmlguibuilder.h> + +#include <libkcal/calendarlocal.h> +#include <libkcal/journal.h> +#include <libkcal/icaldrag.h> +#include <libkdepim/kpimprefs.h> + +#include "knotes/knoteedit.h" + + +class KNotesIconViewItem : public KIconViewItem +{ + public: + KNotesIconViewItem( KIconView *parent, KCal::Journal *journal ) + : KIconViewItem( parent ), + mJournal( journal ) + { + setRenameEnabled( true ); + + KIconEffect effect; + QColor color( journal->customProperty( "KNotes", "BgColor" ) ); + QPixmap icon = KGlobal::iconLoader()->loadIcon( "knotes", KIcon::Desktop ); + icon = effect.apply( icon, KIconEffect::Colorize, 1, color, false ); + setPixmap( icon ); + setText( journal->summary() ); + } + + KCal::Journal *journal() + { + return mJournal; + } + + virtual void setText( const QString& text ) + { + KIconViewItem::setText( text ); + mJournal->setSummary( text ); + } + + private: + KCal::Journal *mJournal; +}; + + +class KNotesIconView : public KIconView +{ + protected: + QDragObject* dragObject() + { + QValueList<KNotesIconViewItem*> selectedItems; + for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) { + if ( it->isSelected() ) + selectedItems.append( static_cast<KNotesIconViewItem *>( it ) ); + } + if ( selectedItems.count() != 1 ) + return KIconView::dragObject(); + + KCal::CalendarLocal cal( KPimPrefs::timezone() ); + KCal::Incidence *i = selectedItems.first()->journal()->clone(); + cal.addIncidence( i ); + KCal::ICalDrag *icd = new KCal::ICalDrag( &cal, this ); + return icd; + } +}; + + +class KNoteEditDlg : public KDialogBase, virtual public KXMLGUIClient +{ + Q_OBJECT + + public: + KNoteEditDlg( QWidget *parent = 0, const char *name = 0 ) + : KDialogBase( Plain, i18n( "Edit Note" ), Ok | Cancel, Ok, + parent, name, true, true ) + { + // this dialog is modal to prevent one from editing the same note twice in two + // different windows + + setInstance( new KInstance( "knotes" ) ); // TODO: hm, memleak?? + setXMLFile( "knotesui.rc" ); + actionCollection()->setWidget( this ); + + QWidget *page = plainPage(); + QVBoxLayout *layout = new QVBoxLayout( page ); + + QHBoxLayout *hbl = new QHBoxLayout( layout, marginHint() ); + QLabel *label = new QLabel( page); + label->setText( i18n( "Name:" ) ); + hbl->addWidget( label,0 ); + mTitleEdit= new KLineEdit( page, "name" ); + hbl->addWidget( mTitleEdit, 1,Qt::AlignVCenter ); + + mNoteEdit = new KNoteEdit( actionCollection(), page ); + mNoteEdit->setTextFormat( RichText ); + mNoteEdit->setFocus(); + + KXMLGUIBuilder builder( page ); + KXMLGUIFactory factory( &builder, this ); + factory.addClient( this ); + + mTool = static_cast<KToolBar *>(factory.container( "note_tool", this )); + + layout->addWidget( mTool ); + layout->addWidget( mNoteEdit ); + } + + QString text() const + { + return mNoteEdit->text(); + } + + void setText( const QString& text ) + { + mNoteEdit->setText( text ); + } + + QString title() const + { + return mTitleEdit->text(); + } + + void setTitle( const QString& text ) + { + mTitleEdit->setText( text ); + } + + void setRichText( bool rt ) + { + mNoteEdit->setTextFormat( rt ? RichText : PlainText ); + } + + private: + KLineEdit *mTitleEdit; + KNoteEdit *mNoteEdit; + KToolBar *mTool; + KPopupMenu *mEditMenu; +}; + + +#endif diff --git a/kontact/plugins/knotes/knotes_plugin.cpp b/kontact/plugins/knotes/knotes_plugin.cpp new file mode 100644 index 000000000..beaaa6331 --- /dev/null +++ b/kontact/plugins/knotes/knotes_plugin.cpp @@ -0,0 +1,97 @@ +/* + This file is part of Kontact + Copyright (c) 2002 Daniel Molkentin <molkentin@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <dcopref.h> +#include <kaboutdata.h> +#include <kaction.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kstatusbar.h> + +#include "core.h" +#include "knotes_part.h" +#include "summarywidget.h" + +#include "knotes_plugin.h" + + +typedef KGenericFactory< KNotesPlugin, Kontact::Core > KNotesPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_knotesplugin, + KNotesPluginFactory( "kontact_knotesplugin" ) ) + + +KNotesPlugin::KNotesPlugin( Kontact::Core *core, const char *, const QStringList & ) + : Kontact::Plugin( core, core, "knotes" ), + mAboutData( 0 ) +{ + setInstance( KNotesPluginFactory::instance() ); + + insertNewAction( new KAction( i18n( "New Note..." ), "knotes", CTRL+SHIFT+Key_N, + this, SLOT( slotNewNote() ), actionCollection(), "new_note" ) ); + insertSyncAction( new KAction( i18n( "Synchronize Notes" ), "reload", 0, + this, SLOT( slotSyncNotes() ), actionCollection(), "knotes_sync" ) ); +} + +KNotesPlugin::~KNotesPlugin() +{ +} + +KParts::ReadOnlyPart* KNotesPlugin::createPart() +{ + return new KNotesPart( this, "notes" ); +} + +Kontact::Summary *KNotesPlugin::createSummaryWidget( QWidget *parentWidget ) +{ + return new KNotesSummaryWidget( this, parentWidget ); +} + +const KAboutData *KNotesPlugin::aboutData() +{ + if ( !mAboutData ) { + mAboutData = new KAboutData( "knotes", I18N_NOOP( "Notes Management" ), + "0.5", I18N_NOOP( "Notes Management" ), + KAboutData::License_GPL_V2, + "(c) 2003-2004 The Kontact developers" ); + mAboutData->addAuthor( "Michael Brade", "Current Maintainer", "brade@kde.org" ); + mAboutData->addAuthor( "Tobias Koenig", "", "tokoe@kde.org" ); + } + + return mAboutData; +} + + +// private slots + +void KNotesPlugin::slotNewNote() +{ + if ( part() ) + static_cast<KNotesPart *>( part() )->newNote(); +} + +void KNotesPlugin::slotSyncNotes() +{ + DCOPRef ref( "kmail", "KMailICalIface" ); + ref.send( "triggerSync", QString("Note") ); +} + +#include "knotes_plugin.moc" + diff --git a/kontact/plugins/knotes/knotes_plugin.h b/kontact/plugins/knotes/knotes_plugin.h new file mode 100644 index 000000000..d4d58cb03 --- /dev/null +++ b/kontact/plugins/knotes/knotes_plugin.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org> + 2004 Michael Brade <brade@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef KNOTES_PLUGIN_H +#define KNOTES_PLUGIN_H + +#include <klocale.h> + +#include "plugin.h" + +class KNotesPart; +class SummaryWidget; + + +class KNotesPlugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + KNotesPlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~KNotesPlugin(); + + virtual Kontact::Summary *createSummaryWidget( QWidget *parentWidget ); + + int weight() const { return 600; } + + const KAboutData *aboutData(); + + protected: + KParts::ReadOnlyPart* createPart(); + + private slots: + void slotNewNote(); + void slotSyncNotes(); + + private: + KAboutData *mAboutData; +}; + +#endif + diff --git a/kontact/plugins/knotes/knotesplugin.desktop b/kontact/plugins/knotes/knotesplugin.desktop new file mode 100644 index 000000000..e7fe8fc0c --- /dev/null +++ b/kontact/plugins/knotes/knotesplugin.desktop @@ -0,0 +1,95 @@ +[Desktop Entry] +Type=Service +Icon=kontact_notes +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_knotesplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPluginHasSummary=true + +X-KDE-PluginInfo-Website=http://pim.kde.org/components/knotes.php +X-KDE-PluginInfo-Name=kontact_knotesplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Notes Component (KNotes Plugin) +Comment[bg]=Приставка за бележки +Comment[ca]=Component de notes (endollable del KNotes) +Comment[da]=Notatkomponent (KNotes-plugin) +Comment[de]=Notizen-Komponente (KNotes-Modul) +Comment[el]=Συσταικό σημειώσεων (Πρόσθετο του KNotes) +Comment[es]=Componente de notas (complemento de KNotes) +Comment[et]=Märkmete plugin (KNotes) +Comment[fr]=Composant de notes (Module KNotes) +Comment[is]=Minnismiðaeining (KNotes íforrit) +Comment[it]=Componente note (plugin KNotes) +Comment[ja]=メモコンポーネント (KNotes プラグイン) +Comment[km]=សមាសភាគចំណាំ (កម្មវិធីជំនួយ KNotes) +Comment[nds]=Notizen-Komponent (KNotes-Moduul) +Comment[nl]=Notitiecomponent (KNotes-plugin) +Comment[pl]=Składnik notatek (wtyczka KNotes) +Comment[ru]=Заметки (модуль KNotes) +Comment[sr]=Компонента белешки (прикључак KNotes-а) +Comment[sr@Latn]=Komponenta beleški (priključak KNotes-a) +Comment[sv]=Anteckningskomponent (Knotes-insticksprogram) +Comment[tr]=Notlar Bileşeni (KNotes Eklentisi) +Comment[zh_CN]=便笺组件(KNotes 插件) +Comment[zh_TW]=便條組件(KNotes 外掛程式) +Name=Notes +Name[af]=Notas +Name[ar]=الملاحظات +Name[be]=Нататкі +Name[bg]=Бележки +Name[br]=Notennoù +Name[bs]=Bilješke +Name[cs]=Poznámky +Name[cy]=Nodiadau +Name[da]=Noter +Name[de]=Notizen +Name[el]=Σημειώσεις +Name[eo]=Notoj +Name[es]=Notas +Name[et]=Märkmed +Name[eu]=Oharrak +Name[fa]=یادداشتها +Name[fi]=Muistio +Name[fy]=Notysjes +Name[ga]=Nótaí +Name[gl]=Notas +Name[he]=פתקים +Name[hi]=टीप +Name[hu]=Feljegyzések +Name[is]=Minnismiðar +Name[it]=Note +Name[ja]=メモ +Name[ka]=ჩანიშვნები +Name[kk]=Жазбалар +Name[km]=ចំណាំ +Name[lt]=Užrašai +Name[mk]=Белешки +Name[ms]=Nota +Name[nds]=Notizen +Name[ne]=टिपोट +Name[nl]=Notities +Name[nn]=Notat +Name[pl]=Notatki +Name[pt]=Notas +Name[pt_BR]=Notas +Name[ro]=Notiţe +Name[ru]=Заметки +Name[se]=Nohtat +Name[sk]=Poznámky +Name[sl]=Notice +Name[sr]=Белешке +Name[sr@Latn]=Beleške +Name[sv]=Anteckningar +Name[ta]=குறிப்புகள் +Name[tg]=Ахборот +Name[th]=บันทึกช่วยจำ +Name[tr]=Notlar +Name[uk]=Примітки +Name[uz]=Yozma xotira +Name[uz@cyrillic]=Ёзма хотира +Name[zh_CN]=便笺 +Name[zh_TW]=備忘錄 diff --git a/kontact/plugins/knotes/knotetip.cpp b/kontact/plugins/knotes/knotetip.cpp new file mode 100644 index 000000000..6e2c998d7 --- /dev/null +++ b/kontact/plugins/knotes/knotetip.cpp @@ -0,0 +1,227 @@ +/* + This file is part of the KDE project + Copyright (C) 2004 Michael Brade <brade@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#include <qtooltip.h> +#include <qlayout.h> +#include <qtextedit.h> + +#include <kapplication.h> +#include <kglobalsettings.h> + +#include "knotetip.h" +#include "knotes_part_p.h" + + +KNoteTip::KNoteTip( KIconView *parent ) + : QFrame( 0, 0, WX11BypassWM | // this will make Seli happy >:-P + WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WStyle_StaysOnTop ), + mFilter( false ), + mView( parent ), + mNoteIVI( 0 ), + mPreview( new QTextEdit( this ) ) +{ + mPreview->setReadOnly( true ); + mPreview->setHScrollBarMode( QScrollView::AlwaysOff ); + mPreview->setVScrollBarMode( QScrollView::AlwaysOff ); + + QBoxLayout *layout = new QVBoxLayout( this ); + layout->addWidget( mPreview ); + + setPalette( QToolTip::palette() ); + setMargin( 1 ); + setFrameStyle( QFrame::Plain | QFrame::Box ); + hide(); +} + +KNoteTip::~KNoteTip() +{ + delete mPreview; + mPreview = 0; +} + +void KNoteTip::setNote( KNotesIconViewItem *item ) +{ + if ( mNoteIVI == item ) + return; + + mNoteIVI = item; + + if ( !mNoteIVI ) { + killTimers(); + if ( isVisible() ) { + setFilter( false ); + hide(); + } + } else { + KCal::Journal *journal = item->journal(); + if ( journal->customProperty( "KNotes", "RichText" ) == "true" ) + mPreview->setTextFormat( Qt::RichText ); + else + mPreview->setTextFormat( Qt::PlainText ); + + QColor fg( journal->customProperty( "KNotes", "FgColor" ) ); + QColor bg( journal->customProperty( "KNotes", "BgColor" ) ); + setColor( fg, bg ); + + mPreview->setText( journal->description() ); + mPreview->zoomTo( 8 ); + mPreview->sync(); + + int w = 400; + int h = mPreview->heightForWidth( w ); + while ( w > 60 && h == mPreview->heightForWidth( w - 20 ) ) + w -= 20; + + QRect desk = KGlobalSettings::desktopGeometry( mNoteIVI->rect().center() ); + resize( w, QMIN( h, desk.height() / 2 - 20 ) ); + + hide(); + killTimers(); + setFilter( true ); + startTimer( 600 ); // delay showing the tooltip for 0.7 sec + } +} + + +// protected, virtual methods + +void KNoteTip::resizeEvent( QResizeEvent *ev ) +{ + QFrame::resizeEvent( ev ); + reposition(); +} + +void KNoteTip::timerEvent( QTimerEvent * ) +{ + killTimers(); + + if ( !isVisible() ) { + startTimer( 15000 ); // show the tooltip for 15 sec + reposition(); + show(); + } else { + setFilter( false ); + hide(); + } +} + +bool KNoteTip::eventFilter( QObject *, QEvent *e ) +{ + switch ( e->type() ) { + case QEvent::Leave: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::FocusIn: + case QEvent::FocusOut: + case QEvent::Wheel: + killTimers(); + setFilter( false ); + hide(); + default: + break; + } + + return false; +} + + +// private stuff + +void KNoteTip::setColor( const QColor &fg, const QColor &bg ) +{ + QPalette newpalette = palette(); + newpalette.setColor( QColorGroup::Background, bg ); + newpalette.setColor( QColorGroup::Foreground, fg ); + newpalette.setColor( QColorGroup::Base, bg ); // text background + newpalette.setColor( QColorGroup::Text, fg ); // text color + newpalette.setColor( QColorGroup::Button, bg ); + + // the shadow + newpalette.setColor( QColorGroup::Midlight, bg.light(110) ); + newpalette.setColor( QColorGroup::Shadow, bg.dark(116) ); + newpalette.setColor( QColorGroup::Light, bg.light(180) ); + newpalette.setColor( QColorGroup::Dark, bg.dark(108) ); + setPalette( newpalette ); + + // set the text color + mPreview->setColor( fg ); +} + + +void KNoteTip::setFilter( bool enable ) +{ + if ( enable == mFilter ) + return; + + if ( enable ) { + kapp->installEventFilter( this ); + QApplication::setGlobalMouseTracking( true ); + } else { + QApplication::setGlobalMouseTracking( false ); + kapp->removeEventFilter( this ); + } + + mFilter = enable; +} + +void KNoteTip::reposition() +{ + if ( !mNoteIVI ) + return; + + QRect rect = mNoteIVI->rect(); + QPoint off = mView->mapToGlobal( mView->contentsToViewport( QPoint( 0, 0 ) ) ); + rect.moveBy( off.x(), off.y() ); + + QPoint pos = rect.center(); + + // should the tooltip be shown to the left or to the right of the ivi? + QRect desk = KGlobalSettings::desktopGeometry( pos ); + if ( rect.center().x() + width() > desk.right() ) { + // to the left + if ( pos.x() - width() < 0 ) + pos.setX( 0 ); + else + pos.setX( pos.x() - width() ); + } + + // should the tooltip be shown above or below the ivi ? + if ( rect.bottom() + height() > desk.bottom() ) { + // above + pos.setY( rect.top() - height() ); + } else + pos.setY( rect.bottom() ); + + move( pos ); + update(); +} diff --git a/kontact/plugins/knotes/knotetip.h b/kontact/plugins/knotes/knotetip.h new file mode 100644 index 000000000..f07b75f0c --- /dev/null +++ b/kontact/plugins/knotes/knotetip.h @@ -0,0 +1,68 @@ +/* + This file is part of the KDE project + Copyright (C) 2004 Michael Brade <brade@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + In addition, as a special exception, the copyright holders give + permission to link the code of this program with any edition of + the Qt library by Trolltech AS, Norway (or with modified versions + of Qt that use the same license as Qt), and distribute linked + combinations including the two. You must obey the GNU General + Public License in all respects for all of the code used other than + Qt. If you modify this file, you may extend this exception to + your version of the file, but you are not obligated to do so. If + you do not wish to do so, delete this exception statement from + your version. +*/ + +#ifndef KNOTETIP_H +#define KNOTETIP_H + +#include <qframe.h> + +class QTextEdit; +class KIconView; +class KNotesIconViewItem; + +class KNoteTip : public QFrame +{ + public: + KNoteTip( KIconView *parent ); + ~KNoteTip(); + + void setNote( KNotesIconViewItem *item ); + + protected: + virtual bool eventFilter( QObject *, QEvent *e ); + virtual void timerEvent( QTimerEvent * ); + virtual void resizeEvent( QResizeEvent * ); + + private: + void setColor( const QColor &fg, const QColor &bg ); + void setFilter( bool enable ); + void reposition(); + + private: + bool mFilter; + + KIconView *mView; + KNotesIconViewItem *mNoteIVI; + + QTextEdit *mPreview; +}; + +#endif diff --git a/kontact/plugins/knotes/summarywidget.cpp b/kontact/plugins/knotes/summarywidget.cpp new file mode 100644 index 000000000..3045ede53 --- /dev/null +++ b/kontact/plugins/knotes/summarywidget.cpp @@ -0,0 +1,164 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qobject.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> + +#include <dcopclient.h> +#include <dcopref.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kurllabel.h> +#include <kstandarddirs.h> + +#include <knotes/resourcenotes.h> +#include <knotes/resourcemanager.h> + +#include "core.h" +#include "plugin.h" + +#include "summarywidget.h" + +KNotesSummaryWidget::KNotesSummaryWidget( Kontact::Plugin *plugin, + QWidget *parent, const char *name ) + : Kontact::Summary( parent, name ), mLayout( 0 ), mPlugin( plugin ) +{ + QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 ); + + QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_notes", + KIcon::Desktop, KIcon::SizeMedium ); + QWidget* header = createHeader( this, icon, i18n( "Notes" ) ); + mainLayout->addWidget( header ); + + mLayout = new QGridLayout( mainLayout, 7, 3, 3 ); + mLayout->setRowStretch( 6, 1 ); + + mCalendar = new KCal::CalendarLocal( QString::fromLatin1("UTC") ); + KNotesResourceManager *manager = new KNotesResourceManager(); + + QObject::connect( manager, SIGNAL( sigRegisteredNote( KCal::Journal* ) ), + this, SLOT( addNote( KCal::Journal* ) ) ); + QObject::connect( manager, SIGNAL( sigDeregisteredNote( KCal::Journal* ) ), + this, SLOT( removeNote( KCal::Journal* ) ) ); + manager->load(); + + + updateView(); +} + +void KNotesSummaryWidget::updateView() +{ + mNotes = mCalendar->journals(); + QLabel *label; + + for ( label = mLabels.first(); label; label = mLabels.next() ) + label->deleteLater(); + mLabels.clear(); + + KIconLoader loader( "knotes" ); + + int counter = 0; + QPixmap pm = loader.loadIcon( "knotes", KIcon::Small ); + + KCal::Journal::List::Iterator it; + if ( mNotes.count() ) { + for (it = mNotes.begin(); it != mNotes.end(); ++it) { + + // Fill Note Pixmap Field + label = new QLabel( this ); + label->setPixmap( pm ); + label->setMaximumWidth( label->minimumSizeHint().width() ); + label->setAlignment( AlignVCenter ); + mLayout->addWidget( label, counter, 0 ); + mLabels.append( label ); + + // File Note Summary Field + QString newtext = (*it)->summary(); + + KURLLabel *urlLabel = new KURLLabel( (*it)->uid(), newtext, this ); + urlLabel->installEventFilter( this ); + urlLabel->setTextFormat(RichText); + urlLabel->setAlignment( urlLabel->alignment() | Qt::WordBreak ); + mLayout->addWidget( urlLabel, counter, 1 ); + mLabels.append( urlLabel ); + + if ( !(*it)->description().isEmpty() ) { + QToolTip::add( urlLabel, (*it)->description().left( 80 ) ); + } + + connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + this, SLOT( urlClicked( const QString& ) ) ); + counter++; + } + + } else { + QLabel *noNotes = new QLabel( i18n( "No Notes Available" ), this ); + noNotes->setAlignment( AlignHCenter | AlignVCenter ); + mLayout->addWidget( noNotes, 0, 1 ); + mLabels.append( noNotes ); + } + + for ( label = mLabels.first(); label; label = mLabels.next() ) + label->show(); +} + +void KNotesSummaryWidget::urlClicked( const QString &/*uid*/ ) +{ + if ( !mPlugin->isRunningStandalone() ) + mPlugin->core()->selectPlugin( mPlugin ); + else + mPlugin->bringToForeground(); +} + +bool KNotesSummaryWidget::eventFilter( QObject *obj, QEvent* e ) +{ + if ( obj->inherits( "KURLLabel" ) ) { + KURLLabel* label = static_cast<KURLLabel*>( obj ); + if ( e->type() == QEvent::Enter ) + emit message( i18n( "Read Note: \"%1\"" ).arg( label->text() ) ); + if ( e->type() == QEvent::Leave ) + emit message( QString::null ); + } + + return Kontact::Summary::eventFilter( obj, e ); +} + +void KNotesSummaryWidget::addNote( KCal::Journal *j ) +{ + mCalendar->addJournal( j ); + updateView(); +} + +void KNotesSummaryWidget::removeNote( KCal::Journal *j ) +{ + mCalendar->deleteJournal( j ); + updateView(); +} + + +#include "summarywidget.moc" diff --git a/kontact/plugins/knotes/summarywidget.h b/kontact/plugins/knotes/summarywidget.h new file mode 100644 index 000000000..f21d829fa --- /dev/null +++ b/kontact/plugins/knotes/summarywidget.h @@ -0,0 +1,71 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SUMMARYWIDGET_H +#define SUMMARYWIDGET_H + +#include "summary.h" + +#include <qmap.h> +#include <qptrlist.h> +#include <qwidget.h> + +#include <libkcal/resourcelocal.h> +#include <libkcal/calendarresources.h> + +class QGridLayout; +class QLabel; + +namespace Kontact { + class Plugin; +} + +class KNotesSummaryWidget : public Kontact::Summary +{ + Q_OBJECT + + public: + KNotesSummaryWidget( Kontact::Plugin *plugin, QWidget *parent, const char *name = 0 ); + + void updateSummary( bool force = false ) { Q_UNUSED( force ); updateView(); } + + protected: + virtual bool eventFilter( QObject *obj, QEvent* e ); + + protected slots: + void urlClicked( const QString& ); + void updateView(); + void addNote( KCal::Journal* ); + void removeNote( KCal::Journal* ); + + private: + KCal::CalendarLocal *mCalendar; + KCal::Journal::List mNotes; + + QGridLayout *mLayout; + + QPtrList<QLabel> mLabels; + Kontact::Plugin *mPlugin; +}; + +#endif diff --git a/kontact/plugins/korganizer/Makefile.am b/kontact/plugins/korganizer/Makefile.am new file mode 100644 index 000000000..a987e4941 --- /dev/null +++ b/kontact/plugins/korganizer/Makefile.am @@ -0,0 +1,58 @@ +# top_srcdir/korganizer is a hack, to get korganizeriface.h +INCLUDES = -I$(top_srcdir)/kontact/interfaces \ + -I$(top_srcdir)/libkdepim \ + -I$(top_srcdir)/korganizer \ + -I$(top_srcdir)/korganizer/interfaces \ + -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_korganizerplugin.la \ + libkontact_todoplugin.la \ + libkontact_journalplugin.la \ + kcm_korgsummary.la + +noinst_LTLIBRARIES = libcommon.la +libcommon_la_SOURCES = korg_uniqueapp.cpp + +libkontact_korganizerplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_korganizerplugin_la_LIBADD = libcommon.la \ + $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) \ + $(top_builddir)/korganizer/libkorganizer_calendar.la +libkontact_korganizerplugin_la_SOURCES = korganizerplugin.cpp \ + kcalendariface.stub \ + summarywidget.cpp \ + korganizeriface.stub + +korganizeriface_DIR = $(top_srcdir)/korganizer +korganizeriface_DCOPIDLNG = true + +libkontact_todoplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_todoplugin_la_LIBADD = libcommon.la \ + $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) \ + $(top_builddir)/korganizer/libkorganizer_calendar.la \ + $(top_builddir)/korganizer/libkorganizer.la +libkontact_todoplugin_la_SOURCES = todoplugin.cpp \ + kcalendariface.stub \ + todosummarywidget.cpp \ + korganizeriface.stub + +libkontact_journalplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_journalplugin_la_LIBADD = libcommon.la \ + $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) \ + $(top_builddir)/korganizer/libkorganizer_calendar.la +libkontact_journalplugin_la_SOURCES = journalplugin.cpp kcalendariface.stub + +kcm_korgsummary_la_SOURCES = kcmkorgsummary.cpp +kcm_korgsummary_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) \ + $(all_libraries) \ + -avoid-version -no-undefined +kcm_korgsummary_la_LIBADD = $(LIB_KDEUI) + +METASOURCES = AUTO + +kcalendariface_DIR = $(top_srcdir)/korganizer + +servicedir = $(kde_servicesdir)/kontact +service_DATA = korganizerplugin.desktop todoplugin.desktop journalplugin.desktop + +kde_services_DATA = kcmkorgsummary.desktop + diff --git a/kontact/plugins/korganizer/journalplugin.cpp b/kontact/plugins/korganizer/journalplugin.cpp new file mode 100644 index 000000000..178901b4c --- /dev/null +++ b/kontact/plugins/korganizer/journalplugin.cpp @@ -0,0 +1,139 @@ +/* + This file is part of Kontact. + + Copyright (c) 2004 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qwidget.h> + +#include <kapplication.h> +#include <kaction.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <dcopclient.h> +#include <dcopref.h> + +#include "core.h" +#include "journalplugin.h" +#include "korg_uniqueapp.h" + + +typedef KGenericFactory< JournalPlugin, Kontact::Core > JournalPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_journalplugin, + JournalPluginFactory( "kontact_journalplugin" ) ) + +JournalPlugin::JournalPlugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "korganizer" ), + mIface( 0 ) +{ + setInstance( JournalPluginFactory::instance() ); + instance()->iconLoader()->addAppDir("kdepim"); + + insertNewAction( new KAction( i18n( "New Journal..." ), "newjournal", + CTRL+SHIFT+Key_J, this, SLOT( slotNewJournal() ), actionCollection(), + "new_journal" ) ); + insertSyncAction( new KAction( i18n( "Synchronize Journal" ), "reload", + 0, this, SLOT( slotSyncJournal() ), actionCollection(), + "journal_sync" ) ); + + + mUniqueAppWatcher = new Kontact::UniqueAppWatcher( + new Kontact::UniqueAppHandlerFactory<KOrganizerUniqueAppHandler>(), this ); +} + +JournalPlugin::~JournalPlugin() +{ +} + +KParts::ReadOnlyPart *JournalPlugin::createPart() +{ + KParts::ReadOnlyPart *part = loadPart(); + + if ( !part ) + return 0; + + dcopClient(); // ensure that we register to DCOP as "korganizer" + mIface = new KCalendarIface_stub( dcopClient(), "kontact", "CalendarIface" ); + + return part; +} + +void JournalPlugin::select() +{ + interface()->showJournalView(); +} + +QStringList JournalPlugin::invisibleToolbarActions() const +{ + QStringList invisible; + invisible += "new_event"; + invisible += "new_todo"; + invisible += "new_journal"; + + invisible += "view_day"; + invisible += "view_list"; + invisible += "view_workweek"; + invisible += "view_week"; + invisible += "view_nextx"; + invisible += "view_month"; + invisible += "view_todo"; + return invisible; +} + +KCalendarIface_stub *JournalPlugin::interface() +{ + if ( !mIface ) { + part(); + } + Q_ASSERT( mIface ); + return mIface; +} + +void JournalPlugin::slotNewJournal() +{ + interface()->openJournalEditor( "" ); +} + +void JournalPlugin::slotSyncJournal() +{ + DCOPRef ref( "kmail", "KMailICalIface" ); + ref.send( "triggerSync", QString("Journal") ); +} + +bool JournalPlugin::createDCOPInterface( const QString& serviceType ) +{ + kdDebug(5602) << k_funcinfo << serviceType << endl; + if ( serviceType == "DCOP/Organizer" || serviceType == "DCOP/Calendar" ) { + if ( part() ) + return true; + } + + return false; +} + +bool JournalPlugin::isRunningStandalone() +{ + return mUniqueAppWatcher->isRunningStandalone(); +} + +#include "journalplugin.moc" diff --git a/kontact/plugins/korganizer/journalplugin.desktop b/kontact/plugins/korganizer/journalplugin.desktop new file mode 100644 index 000000000..8f33753ed --- /dev/null +++ b/kontact/plugins/korganizer/journalplugin.desktop @@ -0,0 +1,89 @@ +[Desktop Entry] +Type=Service +Icon=kontact_journal +ServiceTypes=Kontact/Plugin + +X-KDE-Library=libkontact_journalplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libkorganizerpart +X-KDE-KontactPartExecutableName=korganizer +X-KDE-KontactPluginHasSummary=false + +X-KDE-PluginInfo-Website=http://korganizer.kde.org +X-KDE-PluginInfo-Name=kontact_journalplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Journal Component (KOrganizer Plugin) +Comment[bg]=Приставка за KOrganizer +Comment[ca]=Component de diari (endollable del KOrganizer) +Comment[da]=Journalkomponent (KOrganizer-plugin) +Comment[de]=Journal-Komponente (KOrganizer-Modul) +Comment[el]=Συστατικό χρονικών (Πρόσθετο του KOrganizer) +Comment[es]=Componente de diario (Complemento de KOrganizer) +Comment[et]=Päevikuplugin (KOrganizer) +Comment[fr]= Composant de journal (Module KOrganizer) +Comment[is]=Dagbókareining (Journal KOrganizer íforrit) +Comment[it]=Componente diario (plugin KOrganizer) +Comment[ja]=ジャーナルコンポーネント (KOrganizer プラグイン) +Comment[km]=សមាភាគទិនានុប្បវត្តិ (កម្មវិធីជំនួយ KOrganizer) +Comment[nds]=Daagböker-Komponent (KOrganizer-Moduul) +Comment[nl]=Journaalcomponent (KOrganizer-plugin) +Comment[pl]=Składnik dziennika (wtyczka Korganizer) +Comment[ru]=Журнал (модуль KOrganizer) +Comment[sr]=Компонента дневника (прикључак KOrganizer-а) +Comment[sr@Latn]=Komponenta dnevnika (priključak KOrganizer-a) +Comment[sv]=Journalkomponent (Korganizer-insticksprogram) +Comment[tr]=Günlük Bileşeni (KOrganizer Eklentisi) +Comment[zh_CN]=日记组件(KOrganizer 插件) +Comment[zh_TW]=日誌組件(KOrganizer 外掛程式) +Name=Journal +Name[af]=Joernaal +Name[ar]=اليومية +Name[bg]=Дневник +Name[br]=Deizlevr +Name[ca]=Diari +Name[cs]=Deník +Name[cy]=Dyddlyfr +Name[el]=Χρονικό +Name[eo]=Ĵurnalo +Name[es]=Diario +Name[et]=Päevik +Name[eu]=Egunkaria +Name[fa]=نشریه +Name[fi]=Päiväkirja +Name[fy]=Journaal +Name[ga]=Iris +Name[gl]=Xornal +Name[he]=יומן +Name[hu]=Napló +Name[is]=Dagbók +Name[it]=Diario +Name[ja]=ジャーナル +Name[ka]=ჟურნალი +Name[kk]=Күнделік +Name[km]=ទិនានុប្បវត្តិ +Name[lt]=Dienynas +Name[ms]=Jurnal +Name[nb]=Dagbok +Name[nds]=Daagbook +Name[ne]=जर्नल +Name[nl]=Journaal +Name[nn]=Dagbok +Name[pl]=Dziennik +Name[pt]=Diário +Name[pt_BR]=Diário +Name[ru]=Журнал +Name[sk]=Žurnál +Name[sl]=Dnevnik +Name[sr]=Дневник +Name[sr@Latn]=Dnevnik +Name[ta]=பத்திரிகை +Name[th]=วารสาร +Name[tr]=Günlük +Name[uk]=Журнал +Name[uz]=Kundalik +Name[uz@cyrillic]=Кундалик +Name[zh_CN]=日记 +Name[zh_TW]=日誌 diff --git a/kontact/plugins/korganizer/journalplugin.h b/kontact/plugins/korganizer/journalplugin.h new file mode 100644 index 000000000..668c2b289 --- /dev/null +++ b/kontact/plugins/korganizer/journalplugin.h @@ -0,0 +1,63 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2004 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef KONTACT_JOURNALPLUGIN_H +#define KONTACT_JOURNALPLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include "kcalendariface_stub.h" +#include "plugin.h" +#include "uniqueapphandler.h" + +class JournalPlugin : public Kontact::Plugin +{ + Q_OBJECT + public: + JournalPlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~JournalPlugin(); + + virtual bool createDCOPInterface( const QString& serviceType ); + virtual bool isRunningStandalone(); + int weight() const { return 500; } + + virtual QStringList invisibleToolbarActions() const; + + void select(); + + KCalendarIface_stub *interface(); + + protected: + KParts::ReadOnlyPart *createPart(); + + private slots: + void slotNewJournal(); + void slotSyncJournal(); + + private: + KCalendarIface_stub *mIface; + Kontact::UniqueAppWatcher *mUniqueAppWatcher; +}; + +#endif diff --git a/kontact/plugins/korganizer/kcmkorgsummary.cpp b/kontact/plugins/korganizer/kcmkorgsummary.cpp new file mode 100644 index 000000000..9ab0b6838 --- /dev/null +++ b/kontact/plugins/korganizer/kcmkorgsummary.cpp @@ -0,0 +1,200 @@ +/* + This file is part of Kontact. + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qbuttongroup.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qspinbox.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kaccelmanager.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <klocale.h> + +#include "kcmkorgsummary.h" + +#include <kdepimmacros.h> + +extern "C" +{ + KDE_EXPORT KCModule *create_korgsummary( QWidget *parent, const char * ) + { + return new KCMKOrgSummary( parent, "kcmkorgsummary" ); + } +} + +KCMKOrgSummary::KCMKOrgSummary( QWidget *parent, const char *name ) + : KCModule( parent, name ) +{ + initGUI(); + + customDaysChanged( 1 ); + + connect( mCalendarGroup, SIGNAL( clicked( int ) ), SLOT( modified() ) ); + connect( mCalendarGroup, SIGNAL( clicked( int ) ), SLOT( buttonClicked( int ) ) ); + connect( mTodoGroup, SIGNAL( clicked( int ) ), SLOT( modified() ) ); + connect( mCustomDays, SIGNAL( valueChanged( int ) ), SLOT( modified() ) ); + connect( mCustomDays, SIGNAL( valueChanged( int ) ), SLOT( customDaysChanged( int ) ) ); + + KAcceleratorManager::manage( this ); + + load(); + + KAboutData *about = new KAboutData( I18N_NOOP( "kcmkorgsummary" ), + I18N_NOOP( "Schedule Configuration Dialog" ), + 0, 0, KAboutData::License_GPL, + I18N_NOOP( "(c) 2003 - 2004 Tobias Koenig" ) ); + + about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" ); + setAboutData( about ); +} + +void KCMKOrgSummary::modified() +{ + emit changed( true ); +} + +void KCMKOrgSummary::buttonClicked( int id ) +{ + mCustomDays->setEnabled( id == 4 ); +} + +void KCMKOrgSummary::customDaysChanged( int value ) +{ + mCustomDays->setSuffix( i18n( " day", " days", value ) ); +} + +void KCMKOrgSummary::initGUI() +{ + QVBoxLayout *layout = new QVBoxLayout( this, 0, KDialog::spacingHint() ); + + mCalendarGroup = new QButtonGroup( 0, Vertical, i18n( "Appointments" ), this ); + QVBoxLayout *boxLayout = new QVBoxLayout( mCalendarGroup->layout(), + KDialog::spacingHint() ); + + QLabel *label = new QLabel( i18n( "How many days should the calendar show at once?" ), mCalendarGroup ); + boxLayout->addWidget( label ); + + QRadioButton *button = new QRadioButton( i18n( "One day" ), mCalendarGroup ); + boxLayout->addWidget( button ); + + button = new QRadioButton( i18n( "Five days" ), mCalendarGroup ); + boxLayout->addWidget( button ); + + button = new QRadioButton( i18n( "One week" ), mCalendarGroup ); + boxLayout->addWidget( button ); + + button = new QRadioButton( i18n( "One month" ), mCalendarGroup ); + boxLayout->addWidget( button ); + + QHBoxLayout *hbox = new QHBoxLayout( boxLayout, KDialog::spacingHint() ); + + button = new QRadioButton( "", mCalendarGroup ); + hbox->addWidget( button ); + + mCustomDays = new QSpinBox( 1, 365, 1, mCalendarGroup ); + mCustomDays->setEnabled( false ); + hbox->addWidget( mCustomDays ); + + hbox->addStretch( 1 ); + + layout->addWidget( mCalendarGroup ); + + mTodoGroup = new QButtonGroup( 2, Horizontal, i18n( "To-dos" ), this ); + new QRadioButton( i18n( "Show all to-dos" ), mTodoGroup ); + new QRadioButton( i18n( "Show today's to-dos only" ), mTodoGroup ); + + layout->addWidget( mTodoGroup ); + + layout->addStretch(); +} + +void KCMKOrgSummary::load() +{ + KConfig config( "kcmkorgsummaryrc" ); + + config.setGroup( "Calendar" ); + int days = config.readNumEntry( "DaysToShow", 1 ); + if ( days == 1 ) + mCalendarGroup->setButton( 0 ); + else if ( days == 5 ) + mCalendarGroup->setButton( 1 ); + else if ( days == 7 ) + mCalendarGroup->setButton( 2 ); + else if ( days == 31 ) + mCalendarGroup->setButton( 3 ); + else { + mCalendarGroup->setButton( 4 ); + mCustomDays->setValue( days ); + mCustomDays->setEnabled( true ); + } + + config.setGroup( "Todo" ); + bool allTodos = config.readBoolEntry( "ShowAllTodos", false ); + + if ( allTodos ) + mTodoGroup->setButton( 0 ); + else + mTodoGroup->setButton( 1 ); + + emit changed( false ); +} + +void KCMKOrgSummary::save() +{ + KConfig config( "kcmkorgsummaryrc" ); + + config.setGroup( "Calendar" ); + + int days; + switch ( mCalendarGroup->selectedId() ) { + case 0: days = 1; break; + case 1: days = 5; break; + case 2: days = 7; break; + case 3: days = 31; break; + case 4: + default: days = mCustomDays->value(); break; + } + config.writeEntry( "DaysToShow", days ); + + config.setGroup( "Todo" ); + config.writeEntry( "ShowAllTodos", mTodoGroup->selectedId() == 0 ); + + config.sync(); + + emit changed( false ); +} + +void KCMKOrgSummary::defaults() +{ + mCalendarGroup->setButton( 0 ); + mTodoGroup->setButton( 1 ); + + emit changed( true ); +} + +#include "kcmkorgsummary.moc" diff --git a/kontact/plugins/korganizer/kcmkorgsummary.desktop b/kontact/plugins/korganizer/kcmkorgsummary.desktop new file mode 100644 index 000000000..2f657852e --- /dev/null +++ b/kontact/plugins/korganizer/kcmkorgsummary.desktop @@ -0,0 +1,125 @@ +[Desktop Entry] +Icon=kontact_date +Type=Service +ServiceTypes=KCModule + +X-KDE-ModuleType=Library +X-KDE-Library=korgsummary +X-KDE-FactoryName=korgsummary +X-KDE-ParentApp=kontact_korganizerplugin,kontact_todoplugin +X-KDE-ParentComponents=kontact_korganizerplugin,kontact_todoplugin +X-KDE-CfgDlgHierarchy=KontactSummary + +Name=Appointment and To-do Overview +Name[bg]=Преглед на срещи и задачи +Name[ca]=Resum de cites i tasques pendents +Name[da]=Oversigt over møder og gøremål +Name[de]=Übersicht über Termine und Aufgaben +Name[el]=Επισκόπηση ραντεβού και προς υλοποίηση εργασιών +Name[es]=Resumen de citas y tareas pendientes +Name[et]=Kohtumised ja ülesannete ülevaade +Name[fr]=Aperçu des rendez-vous et des tâches +Name[is]=Yfirlit um fundi og verkþætti +Name[it]=Panoramica appuntamenti e cose da fare +Name[ja]=約束と To-Do の要約 +Name[km]=ទិដ្ឋភាពការណាត់ និងការងារត្រូវធ្វើ +Name[nds]=Termin- un Opgaven-Översicht +Name[nl]=Overzicht van evenementen en taken +Name[pl]=Spotkania i zadania +Name[ru]=Сводка встреч и задач +Name[sr]=Преглед састанака и обавеза +Name[sr@Latn]=Pregled sastanaka i obaveza +Name[sv]=Översikt av möten och uppgifter +Name[tr]=Randevulara ve Yapılacaklara Genel Bakış +Name[zh_CN]=约会和待办概览 +Name[zh_TW]=約會與待辦事項概觀 +Comment=Appointments and To-dos Summary Setup +Comment[af]=Afsprake en te-doen opsomming opstelling +Comment[bg]=Приставка за обобщен преглед на срещите и задачите +Comment[ca]=Configuració del resum de cites i tasques pendents +Comment[cs]=Nastavení souhrnu schůzek a úkolů +Comment[da]=Indstilling af oversigt over møder og gøremål +Comment[de]=Einstellung der Übersicht über Termine und Aufgaben +Comment[el]=Ρύθμιση ραντεβού και προς υλοποίηση εργασιών +Comment[es]=Configuración del resumen de citas y de tareas pendientes +Comment[et]=Kohtumiste ja ülesannete kokkuvõtte seadistus +Comment[eu]=Hitzordu eta egitekoen laburpenen konfigurazioa +Comment[fa]=برپایی خلاصۀ قرار ملاقاتها و کارهایی که باید انجام شوند +Comment[fi]=Tapaamiset ja tehtävät -yhteenvedon asetukset +Comment[fr]=Configuration du résumé des évènements et des tâches +Comment[fy]=Oersichtsynstellings foar eveneminten en taken +Comment[gl]=Configuración de sumarios de tarefas e notas +Comment[hu]=A találkozók és feladatok áttekintőjének beállítása +Comment[is]=Uppsetning á yfirliti yfir fundi og verkefni +Comment[it]=Impostazioni sommario appuntamenti e cose da fare +Comment[ja]=約束と To-Do の要約設定 +Comment[ka]=შეხვედრათა და გასაკეთებელთა რეზიუმეს დაყენება +Comment[kk]=Кездесулер мен Жоспарлар тұжырымының баптау +Comment[km]=រៀបចំសេចក្ដីសង្ខេបការណាត់ និងការងារត្រូវធ្វើ +Comment[lt]=Susitikimų ir užduočių santraukos nustatymai +Comment[mk]=Поставување на преглед за состаноци и задачи +Comment[nb]=Oppsett av sammendraget av gjøremål og avtaler +Comment[nds]=Termin- un Opgaven-Översicht instellen +Comment[ne]=भेटघाट र गर्नुपर्ने कार्यहरूको सारांश सेटअप +Comment[nl]=Overzichtsinstellingen voor evenementen en taken +Comment[nn]=Oppsett av samandrag av avtalar og oppgåver +Comment[pl]=Ustawienia podsumowania spotkań i zadań +Comment[pt]=Configuração do Sumário de Compromissos e A-fazeres +Comment[pt_BR]=Configuração do Resumo de Compromissos e Tarefas +Comment[ru]=Настройка сводки встреч и задач +Comment[sk]=Nastavenie súhrnu pripomienok a úloh +Comment[sl]=Nastavitve povzetka sestankov in opravil +Comment[sr]=Подешавање сажетка састанака и обавеза +Comment[sr@Latn]=Podešavanje sažetka sastanaka i obaveza +Comment[sv]=Inställning av översikt av möten och uppgifter +Comment[tr]=Özel Günler ve Yapılacaklar Listesi Yapılandırması +Comment[uk]=Налаштування зведення зустрічей і завдань +Comment[zh_CN]=约会和待办摘要设置 +Comment[zh_TW]=約會與待辦事項摘要設定 +Keywords=calendar, todos, configure, settings +Keywords[af]=calendar,todos,configure,settings +Keywords[be]=каляндар, заданні, настроіць, настаўленні, calendar, todos, configure, settings +Keywords[bg]=календар, задачи, организатор, calendar, todos, configure, settings +Keywords[bs]=calendar, todos, configure, settings, kalendar, zadaci, postavke +Keywords[ca]=calendari, pendents, configuració, arranjament +Keywords[cs]=kalendář,úkoly,nastavit,nastavení +Keywords[da]=kalender, gøremål, indstil, opsætning +Keywords[de]=Kalender,Aufgaben,einstellen,Einstellungen,Einrichten +Keywords[el]=ημερολόγιο, προς υλοποίηση, ρύθμιση, ρυθμίσεις +Keywords[es]=calendario, tareas pendientes, configurar, opciones +Keywords[et]=kalender, ülesanded, seadistamine, seadistused +Keywords[eu]=egutegia, egitekoak, konfiguratu, ezarpenak +Keywords[fa]=تقویم، کارهای انجامی، پیکربندی، تنظیمات +Keywords[fi]=kalenteri, tehtävät, muokkaa, asetukset +Keywords[fr]=calendrier,agenda,tâches,configurer,paramètres,paramètre +Keywords[fy]=kalinder,aginda,taken,todo,ynstellings,konfiguraasje +Keywords[ga]=féilire, tascanna, cumraigh, socruithe +Keywords[gl]=calendario, pendentes, configurar, opcións +Keywords[he]=calendar, todos, configure, settings, יומן, יומנים, משימות, מטלות, הגדרות, תצורה +Keywords[hu]=naptár,feladatok,konfigurálás,beállítások +Keywords[is]=dagatal, verkefni, stillingar, stilla +Keywords[it]=calendario, cose da fare, configura, impostazioni +Keywords[ja]=カレンダー, To-Do, 設定 +Keywords[ka]=კალენდარი,გასაკეთებლები,კონფიგურაცია,პარამეტრები +Keywords[km]=ប្រតិទិន,ការងារត្រូវធ្វើ,កំណត់រចនាសម្ព័ន្ធ,ការកំណត់ +Keywords[lt]=calendar, todos, configure, settings, kalendorius, darbai, konfigūruoti, nustatymai +Keywords[ms]=kalendar, tugasan, konfigur, seting +Keywords[nb]=kalender, gjørelister, oppsett, innstillinger +Keywords[nds]=Kalenner,Opgaven,Opgaav,instellen,Mööt,Möten +Keywords[ne]=क्यालेन्डर, गर्नुपर्ने कार्यहरू, कन्फिगर, सेटिङ +Keywords[nl]=kalender,agenda,taken,todo,instellingen,configuratie +Keywords[nn]=kalender,hugselister,oppsett,innstillingar +Keywords[pl]=kalendarz,do zrobienia,konfiguracja,ustawienia +Keywords[pt]=calendário, a fazer, configurar, configuração +Keywords[pt_BR]=calendário, pendências, configurar, configurações +Keywords[ru]=calendar,todos,configure,settings,настройка,календарь,задачи +Keywords[sk]=kalendár,úlohy,nastavenie +Keywords[sl]=koledar,za narediti,nastavitve,nastavi +Keywords[sr]=calendar, todos, configure, settings, календар, послови, подеси, поставке +Keywords[sr@Latn]=calendar, todos, configure, settings, kalendar, poslovi, podesi, postavke +Keywords[sv]=kalender, uppgifter, anpassa, inställningar +Keywords[ta]=நாள்காட்டி,செய்யவேண்டியவைகள்,கட்டமைப்பு,அமைவுகள் +Keywords[tg]=calendar, todos, configure, settings,танзимот, тақвим,вазифа +Keywords[tr]=takvim, yapılacaklar, yapılandır, yapılandırma +Keywords[uk]=календар, завдання, налаштування, параметри +Keywords[zh_CN]=calendar, todos, configure, settings, 日历, 待办事项, 配置, 设置 diff --git a/kontact/plugins/korganizer/kcmkorgsummary.h b/kontact/plugins/korganizer/kcmkorgsummary.h new file mode 100644 index 000000000..cf484e56d --- /dev/null +++ b/kontact/plugins/korganizer/kcmkorgsummary.h @@ -0,0 +1,56 @@ +/* + This file is part of Kontact. + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KCMKORGSUMMARY_H +#define KCMKORGSUMMARY_H + +#include <kcmodule.h> + +class QSpinxBox; +class QButtonGroup; + +class KCMKOrgSummary : public KCModule +{ + Q_OBJECT + + public: + KCMKOrgSummary( QWidget *parent = 0, const char *name = 0 ); + + virtual void load(); + virtual void save(); + virtual void defaults(); + + private slots: + void modified(); + void buttonClicked( int ); + void customDaysChanged( int ); + + private: + void initGUI(); + + QButtonGroup *mCalendarGroup; + QButtonGroup *mTodoGroup; + QSpinBox *mCustomDays; +}; + +#endif diff --git a/kontact/plugins/korganizer/korg_uniqueapp.cpp b/kontact/plugins/korganizer/korg_uniqueapp.cpp new file mode 100644 index 000000000..b70042353 --- /dev/null +++ b/kontact/plugins/korganizer/korg_uniqueapp.cpp @@ -0,0 +1,38 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 David Faure <faure@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "korg_uniqueapp.h" +#include <kdebug.h> +#include "../../korganizer/korganizer_options.h" + +void KOrganizerUniqueAppHandler::loadCommandLineOptions() +{ + KCmdLineArgs::addCmdLineOptions( korganizer_options ); +} + +int KOrganizerUniqueAppHandler::newInstance() +{ + //kdDebug(5602) << k_funcinfo << endl; + // Ensure part is loaded + (void)plugin()->part(); + // TODO handle command line options + return Kontact::UniqueAppHandler::newInstance(); +} diff --git a/kontact/plugins/korganizer/korg_uniqueapp.h b/kontact/plugins/korganizer/korg_uniqueapp.h new file mode 100644 index 000000000..d21f8c526 --- /dev/null +++ b/kontact/plugins/korganizer/korg_uniqueapp.h @@ -0,0 +1,37 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 David Faure <faure@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KORG_UNIQUEAPP_H +#define KORG_UNIQUEAPP_H + +#include <uniqueapphandler.h> + +class KOrganizerUniqueAppHandler : public Kontact::UniqueAppHandler +{ +public: + KOrganizerUniqueAppHandler( Kontact::Plugin* plugin ) : Kontact::UniqueAppHandler( plugin ) {} + virtual void loadCommandLineOptions(); + virtual int newInstance(); +}; + + +#endif /* KORG_UNIQUEAPP_H */ + diff --git a/kontact/plugins/korganizer/korganizerplugin.cpp b/kontact/plugins/korganizer/korganizerplugin.cpp new file mode 100644 index 000000000..7aef2e6e0 --- /dev/null +++ b/kontact/plugins/korganizer/korganizerplugin.cpp @@ -0,0 +1,227 @@ +/* + This file is part of Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qcursor.h> +#include <qfile.h> +#include <qwidget.h> +#include <qdragobject.h> + +#include <kapplication.h> +#include <kabc/vcardconverter.h> +#include <kaction.h> +#include <dcopref.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> + +#include <dcopclient.h> + +#include <libkdepim/kvcarddrag.h> +#include <libkdepim/maillistdrag.h> + +#include "core.h" +#include "summarywidget.h" +#include "korganizerplugin.h" +#include "korg_uniqueapp.h" + +typedef KGenericFactory< KOrganizerPlugin, Kontact::Core > KOrganizerPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_korganizerplugin, + KOrganizerPluginFactory( "kontact_korganizerplugin" ) ) + +KOrganizerPlugin::KOrganizerPlugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "korganizer" ), + mIface( 0 ) +{ + + setInstance( KOrganizerPluginFactory::instance() ); + instance()->iconLoader()->addAppDir("kdepim"); + + insertNewAction( new KAction( i18n( "New Event..." ), "newappointment", + CTRL+SHIFT+Key_E, this, SLOT( slotNewEvent() ), actionCollection(), + "new_event" ) ); + + insertSyncAction( new KAction( i18n( "Synchronize Calendar" ), "reload", + 0, this, SLOT( slotSyncEvents() ), actionCollection(), + "korganizer_sync" ) ); + + mUniqueAppWatcher = new Kontact::UniqueAppWatcher( + new Kontact::UniqueAppHandlerFactory<KOrganizerUniqueAppHandler>(), this ); +} + +KOrganizerPlugin::~KOrganizerPlugin() +{ +} + +Kontact::Summary *KOrganizerPlugin::createSummaryWidget( QWidget *parent ) +{ + return new SummaryWidget( this, parent ); +} + +KParts::ReadOnlyPart *KOrganizerPlugin::createPart() +{ + KParts::ReadOnlyPart *part = loadPart(); + + if ( !part ) + return 0; + + mIface = new KCalendarIface_stub( dcopClient(), "kontact", "CalendarIface" ); + + return part; +} + +QString KOrganizerPlugin::tipFile() const +{ + QString file = ::locate("data", "korganizer/tips"); + return file; +} + +QStringList KOrganizerPlugin::invisibleToolbarActions() const +{ + QStringList invisible; + invisible += "new_event"; + invisible += "new_todo"; + invisible += "new_journal"; + + invisible += "view_todo"; + invisible += "view_journal"; + return invisible; +} + +void KOrganizerPlugin::select() +{ + interface()->showEventView(); +} + +KCalendarIface_stub *KOrganizerPlugin::interface() +{ + if ( !mIface ) { + part(); + } + Q_ASSERT( mIface ); + return mIface; +} + +void KOrganizerPlugin::slotNewEvent() +{ + interface()->openEventEditor( "" ); +} + +void KOrganizerPlugin::slotSyncEvents() +{ + DCOPRef ref( "kmail", "KMailICalIface" ); + ref.send( "triggerSync", QString("Calendar") ); +} + +bool KOrganizerPlugin::createDCOPInterface( const QString& serviceType ) +{ + kdDebug(5602) << k_funcinfo << serviceType << endl; + if ( serviceType == "DCOP/Organizer" || serviceType == "DCOP/Calendar" ) { + if ( part() ) + return true; + } + + return false; +} + +bool KOrganizerPlugin::isRunningStandalone() +{ + return mUniqueAppWatcher->isRunningStandalone(); +} + +bool KOrganizerPlugin::canDecodeDrag( QMimeSource *mimeSource ) +{ + return QTextDrag::canDecode( mimeSource ) || + KPIM::MailListDrag::canDecode( mimeSource ); +} + +void KOrganizerPlugin::processDropEvent( QDropEvent *event ) +{ + QString text; + + KABC::VCardConverter converter; + if ( KVCardDrag::canDecode( event ) && KVCardDrag::decode( event, text ) ) { + KABC::Addressee::List contacts = converter.parseVCards( text ); + KABC::Addressee::List::Iterator it; + + QStringList attendees; + for ( it = contacts.begin(); it != contacts.end(); ++it ) { + QString email = (*it).fullEmail(); + if ( email.isEmpty() ) + attendees.append( (*it).realName() + "<>" ); + else + attendees.append( email ); + } + + interface()->openEventEditor( i18n( "Meeting" ), QString::null, QString::null, + attendees ); + return; + } + + if ( QTextDrag::decode( event, text ) ) { + kdDebug(5602) << "DROP:" << text << endl; + interface()->openEventEditor( text ); + return; + } + + KPIM::MailList mails; + if ( KPIM::MailListDrag::decode( event, mails ) ) { + if ( mails.count() != 1 ) { + KMessageBox::sorry( core(), + i18n("Drops of multiple mails are not supported." ) ); + } else { + KPIM::MailSummary mail = mails.first(); + QString txt = i18n("From: %1\nTo: %2\nSubject: %3").arg( mail.from() ) + .arg( mail.to() ).arg( mail.subject() ); + + KTempFile tf; + tf.setAutoDelete( true ); + QString uri = QString::fromLatin1("kmail:") + QString::number( mail.serialNumber() ); + tf.file()->writeBlock( event->encodedData( "message/rfc822" ) ); + tf.close(); + interface()->openEventEditor( i18n("Mail: %1").arg( mail.subject() ), txt, + uri, tf.name(), QStringList(), "message/rfc822" ); + } + return; + } + + KMessageBox::sorry( core(), i18n("Cannot handle drop events of type '%1'.") + .arg( event->format() ) ); +} + +void KOrganizerPlugin::loadProfile( const QString& directory ) +{ + DCOPRef ref( "korganizer", "KOrganizerIface" ); + ref.send( "loadProfile", directory ); +} + +void KOrganizerPlugin::saveToProfile( const QString& directory ) const +{ + DCOPRef ref( "korganizer", "KOrganizerIface" ); + ref.send( "saveToProfile", directory ); +} + +#include "korganizerplugin.moc" diff --git a/kontact/plugins/korganizer/korganizerplugin.desktop b/kontact/plugins/korganizer/korganizerplugin.desktop new file mode 100644 index 000000000..7a29913c1 --- /dev/null +++ b/kontact/plugins/korganizer/korganizerplugin.desktop @@ -0,0 +1,101 @@ +[Desktop Entry] +Type=Service +Icon=kontact_date +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_korganizerplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libkorganizerpart +X-KDE-KontactPartExecutableName=korganizer +X-KDE-KontactPluginHasSummary=true + +X-KDE-PluginInfo-Website=http://korganizer.kde.org +X-KDE-PluginInfo-Name=kontact_korganizerplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Calendar Component (KOrganizer Plugin) +Comment[bg]=Приставка за KOrganizer +Comment[ca]=Component de calendari (endollable del KOrganizer) +Comment[da]=Kalenderkomponent (KOrganizer-plugin) +Comment[de]=Kalender-Komponente (KOrganizer-Modul) +Comment[el]=Συστατικό ημερολογίου (Πρόσθετο του KOrganizer) +Comment[es]=Componente de calendario (complemento de KOrganizer) +Comment[et]=Kalendriplugin (KOrganizer) +Comment[fr]= Composant de calendrier (Module KOrganizer) +Comment[is]=Dagatalseining (KOrganizer íforrit) +Comment[it]=Componente calendario (plugin KOrganizer) +Comment[ja]=カレンダーコンポーネント (KOrganizer プラグイン) +Comment[km]=សមាសភាគប្រតិទិន (កម្មវិធីជំនួយ KOrganizer) +Comment[nds]=Kalenner-Komponent (KOrganizer-Moduul) +Comment[nl]=Agendacomponent (KOrganizer-plugin) +Comment[pl]=Składnik kalendarza (wtyczka KOrganizer) +Comment[ru]=Календарь (модуль KOrganizer) +Comment[sk]=Kalendárový komponent (Modeul pre KOrganizer) +Comment[sr]=Компонента календара (прикључак KOrganizer-а) +Comment[sr@Latn]=Komponenta kalendara (priključak KOrganizer-a) +Comment[sv]=Kalenderkomponent (Korganizer-insticksprogram) +Comment[tr]=Takvim Bileşeni (KOrganizer Eklentisi) +Comment[zh_CN]=日历组件(KOrganizer 插件) +Comment[zh_TW]=行事曆組件(KOrganizer 外掛程式) +Name=Calendar +Name[af]=Kalender +Name[ar]=التقويم +Name[be]=Каляндар +Name[bg]=Календар +Name[br]=Deiziadur +Name[bs]=Kalendar +Name[ca]=Calendari +Name[cs]=Kalendář +Name[cy]=Calendr +Name[da]=Kalender +Name[de]=Kalender +Name[el]=Ημερολόγιο +Name[eo]=Kalendaro +Name[es]=Calendario +Name[et]=Kalender +Name[eu]=Egutegia +Name[fa]=تقویم +Name[fi]=Kalenteri +Name[fr]=Calendrier +Name[fy]=Aginda +Name[ga]=Féilire +Name[gl]=Calendario +Name[he]=לוח שנה +Name[hi]=कैलेन्डर +Name[hu]=Naptár +Name[is]=Dagatal +Name[it]=Calendario +Name[ja]=カレンダー +Name[ka]=კალენდარი +Name[kk]=Күнтізбе +Name[km]=ប្រតិទិន +Name[lt]=Kalendorius +Name[mk]=Календар +Name[ms]=Kalendar +Name[nb]=Kalender +Name[nds]=Kalenner +Name[ne]=क्यालेन्डर +Name[nl]=Agenda +Name[nn]=Kalender +Name[pa]=ਕੈਲੰਡਰ +Name[pl]=Kalendarz +Name[pt]=Calendário +Name[pt_BR]=Calendário +Name[ru]=Календарь +Name[se]=Kaleandar +Name[sk]=Kalendár +Name[sl]=Koledar +Name[sr]=Календар +Name[sr@Latn]=Kalendar +Name[sv]=Kalender +Name[ta]=நாள்காட்டி +Name[tg]=Тақвим +Name[th]=บันทึกประจำวัน +Name[tr]=Takvim +Name[uk]=Календар +Name[uz]=Kalendar +Name[uz@cyrillic]=Календар +Name[zh_CN]=日历 +Name[zh_TW]=行事曆 diff --git a/kontact/plugins/korganizer/korganizerplugin.h b/kontact/plugins/korganizer/korganizerplugin.h new file mode 100644 index 000000000..df8259961 --- /dev/null +++ b/kontact/plugins/korganizer/korganizerplugin.h @@ -0,0 +1,75 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KORGANIZER_PLUGIN_H +#define KORGANIZER_PLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include "kcalendariface_stub.h" +#include "plugin.h" +#include "uniqueapphandler.h" + +class KOrganizerPlugin : public Kontact::Plugin +{ + Q_OBJECT + + public: + KOrganizerPlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~KOrganizerPlugin(); + + virtual bool createDCOPInterface( const QString& serviceType ); + virtual bool isRunningStandalone(); + int weight() const { return 400; } + + bool canDecodeDrag( QMimeSource * ); + void processDropEvent( QDropEvent * ); + + virtual Kontact::Summary *createSummaryWidget( QWidget *parent ); + + virtual QString tipFile() const; + virtual QStringList invisibleToolbarActions() const; + + void select(); + + KCalendarIface_stub *interface(); + + + void loadProfile( const QString& path ); + void saveToProfile( const QString& path ) const; + + protected: + KParts::ReadOnlyPart *createPart(); + + private slots: + void slotNewEvent(); + void slotSyncEvents(); + + private: + KCalendarIface_stub *mIface; + Kontact::UniqueAppWatcher *mUniqueAppWatcher; +}; + +#endif diff --git a/kontact/plugins/korganizer/summarywidget.cpp b/kontact/plugins/korganizer/summarywidget.cpp new file mode 100644 index 000000000..68742248f --- /dev/null +++ b/kontact/plugins/korganizer/summarywidget.cpp @@ -0,0 +1,313 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qcursor.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> + +#include <kdialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kparts/part.h> +#include <kpopupmenu.h> +#include <kstandarddirs.h> +#include <kurllabel.h> +#include <libkcal/event.h> +#include <libkcal/resourcecalendar.h> +#include <libkcal/resourcelocal.h> +#include <libkcal/incidenceformatter.h> +#include <libkdepim/kpimprefs.h> + +#include "korganizeriface_stub.h" + +#include "core.h" +#include "plugin.h" +#include "korganizerplugin.h" + +#include "korganizer/stdcalendar.h" + +#include "summarywidget.h" + +SummaryWidget::SummaryWidget( KOrganizerPlugin *plugin, QWidget *parent, + const char *name ) + : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 ) +{ + QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 ); + + QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_date", + KIcon::Desktop, KIcon::SizeMedium ); + QWidget *header = createHeader( this, icon, i18n( "Calendar" ) ); + mainLayout->addWidget( header ); + + mLayout = new QGridLayout( mainLayout, 7, 5, 3 ); + mLayout->setRowStretch( 6, 1 ); + + mCalendar = KOrg::StdCalendar::self(); + mCalendar->load(); + + connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) ); + connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ), + SLOT( updateView() ) ); + + updateView(); +} + +SummaryWidget::~SummaryWidget() +{ +} + +void SummaryWidget::updateView() +{ + mLabels.setAutoDelete( true ); + mLabels.clear(); + mLabels.setAutoDelete( false ); + + KIconLoader loader( "kdepim" ); + + KConfig config( "kcmkorgsummaryrc" ); + + config.setGroup( "Calendar" ); + int days = config.readNumEntry( "DaysToShow", 1 ); + + QLabel *label = 0; + int counter = 0; + QPixmap pm = loader.loadIcon( "appointment", KIcon::Small ); + + QDate dt; + QDate currentDate = QDate::currentDate(); + for ( dt=currentDate; + dt<=currentDate.addDays( days - 1 ); + dt=dt.addDays(1) ) { + + KCal::Event *ev; + + KCal::Event::List events_orig = mCalendar->events( dt ); + KCal::Event::List::ConstIterator it = events_orig.begin(); + + KCal::Event::List events; + events.setAutoDelete( true ); + QDateTime qdt; + + // prevent implicitely sharing while finding recurring events + // replacing the QDate with the currentDate + for ( ; it != events_orig.end(); ++it ) { + ev = (*it)->clone(); + if ( ev->recursOn( dt ) ) { + qdt = ev->dtStart(); + qdt.setDate( dt ); + ev->setDtStart( qdt ); + } + events.append( ev ); + } + + // sort the events for this date by summary + events = KCal::Calendar::sortEvents( &events, + KCal::EventSortSummary, + KCal::SortDirectionAscending ); + // sort the events for this date by start date + events = KCal::Calendar::sortEvents( &events, + KCal::EventSortStartDate, + KCal::SortDirectionAscending ); + + for ( it=events.begin(); it!=events.end(); ++it ) { + ev = *it; + + // Count number of days remaining in multiday event + int span=1; int dayof=1; + if ( ev->isMultiDay() ) { + QDate d = ev->dtStart().date(); + if ( d < currentDate ) { + d = currentDate; + } + while ( d < ev->dtEnd().date() ) { + if ( d < dt ) { + dayof++; + } + span++; + d=d.addDays( 1 ); + } + } + + // If this date is part of a floating, multiday event, then we + // only make a print for the first day of the event. + if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 ) continue; + + // Fill Appointment Pixmap Field + label = new QLabel( this ); + label->setPixmap( pm ); + label->setMaximumWidth( label->minimumSizeHint().width() ); + label->setAlignment( AlignVCenter ); + mLayout->addWidget( label, counter, 0 ); + mLabels.append( label ); + + // Fill Event Date Field + bool makeBold = false; + QString datestr; + + // Modify event date for printing + QDate sD = QDate::QDate( dt.year(), dt.month(), dt.day() ); + if ( ( sD.month() == currentDate.month() ) && + ( sD.day() == currentDate.day() ) ) { + datestr = i18n( "Today" ); + makeBold = true; + } else if ( ( sD.month() == currentDate.addDays( 1 ).month() ) && + ( sD.day() == currentDate.addDays( 1 ).day() ) ) { + datestr = i18n( "Tomorrow" ); + } else { + datestr = KGlobal::locale()->formatDate( sD ); + } + + // Print the date span for multiday, floating events, for the + // first day of the event only. + if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) { + datestr = KGlobal::locale()->formatDate( ev->dtStart().date() ); + datestr += " -\n " + + KGlobal::locale()->formatDate( sD.addDays( span-1 ) ); + } + + label = new QLabel( datestr, this ); + label->setAlignment( AlignLeft | AlignVCenter ); + if ( makeBold ) { + QFont font = label->font(); + font.setBold( true ); + label->setFont( font ); + } + mLayout->addWidget( label, counter, 1 ); + mLabels.append( label ); + + // Fill Event Summary Field + QString newtext = ev->summary(); + if ( ev->isMultiDay() && !ev->doesFloat() ) { + newtext.append( QString(" (%1/%2)").arg( dayof ).arg( span ) ); + } + + KURLLabel *urlLabel = new KURLLabel( this ); + urlLabel->setText( newtext ); + urlLabel->setURL( ev->uid() ); + urlLabel->installEventFilter( this ); + urlLabel->setAlignment( urlLabel->alignment() | Qt::WordBreak ); + mLayout->addWidget( urlLabel, counter, 2 ); + mLabels.append( urlLabel ); + + connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + this, SLOT( viewEvent( const QString& ) ) ); + connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ), + this, SLOT( popupMenu( const QString& ) ) ); + + QString tipText( KCal::IncidenceFormatter::toolTipString( ev, true ) ); + if ( !tipText.isEmpty() ) { + QToolTip::add( urlLabel, tipText ); + } + + // Fill Event Time Range Field (only for non-floating Events) + if ( !ev->doesFloat() ) { + QTime sST = ev->dtStart().time(); + QTime sET = ev->dtEnd().time(); + if ( ev->isMultiDay() ) { + if ( ev->dtStart().date() < dt ) { + sST = QTime::QTime( 0, 0 ); + } + if ( ev->dtEnd().date() > dt ) { + sET = QTime::QTime( 23, 59 ); + } + } + datestr = i18n( "Time from - to", "%1 - %2" ) + .arg( KGlobal::locale()->formatTime( sST ) ) + .arg( KGlobal::locale()->formatTime( sET ) ); + label = new QLabel( datestr, this ); + label->setAlignment( AlignLeft | AlignVCenter ); + mLayout->addWidget( label, counter, 3 ); + mLabels.append( label ); + } + + counter++; + } + } + + if ( !counter ) { + QLabel *noEvents = new QLabel( + i18n( "No appointments pending within the next day", + "No appointments pending within the next %n days", + days ), this, "nothing to see" ); + noEvents->setAlignment( AlignHCenter | AlignVCenter ); + mLayout->addWidget( noEvents, 0, 2 ); + mLabels.append( noEvents ); + } + + for ( label = mLabels.first(); label; label = mLabels.next() ) + label->show(); +} + +void SummaryWidget::viewEvent( const QString &uid ) +{ + mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded + KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" ); + iface.editIncidence( uid ); +} + +void SummaryWidget::removeEvent( const QString &uid ) +{ + mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded + KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" ); + iface.deleteIncidence( uid, false ); +} + +void SummaryWidget::popupMenu( const QString &uid ) +{ + KPopupMenu popup( this ); + QToolTip::remove( this ); + popup.insertItem( i18n( "&Edit Appointment..." ), 0 ); + popup.insertItem( KGlobal::iconLoader()->loadIcon( "editdelete", KIcon::Small), + i18n( "&Delete Appointment" ), 1 ); + + switch ( popup.exec( QCursor::pos() ) ) { + case 0: + viewEvent( uid ); + break; + case 1: + removeEvent( uid ); + break; + } +} + +bool SummaryWidget::eventFilter( QObject *obj, QEvent* e ) +{ + if ( obj->inherits( "KURLLabel" ) ) { + KURLLabel* label = static_cast<KURLLabel*>( obj ); + if ( e->type() == QEvent::Enter ) + emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) ); + if ( e->type() == QEvent::Leave ) + emit message( QString::null ); + } + + return Kontact::Summary::eventFilter( obj, e ); +} + +QStringList SummaryWidget::configModules() const +{ + return QStringList( "kcmkorgsummary.desktop" ); +} + +#include "summarywidget.moc" diff --git a/kontact/plugins/korganizer/summarywidget.h b/kontact/plugins/korganizer/summarywidget.h new file mode 100644 index 000000000..c9c572eca --- /dev/null +++ b/kontact/plugins/korganizer/summarywidget.h @@ -0,0 +1,70 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SUMMARYWIDGET_H +#define SUMMARYWIDGET_H + +#include <qptrlist.h> +#include <qwidget.h> + +#include <libkcal/calendarresources.h> + +#include "summary.h" + +class QGridLayout; +class QLabel; + +class KOrganizerPlugin; + +class SummaryWidget : public Kontact::Summary +{ + Q_OBJECT + + public: + SummaryWidget( KOrganizerPlugin *plugin, QWidget *parent, + const char *name = 0 ); + ~SummaryWidget(); + + int summaryHeight() const { return 3; } + QStringList configModules() const; + public slots: + void updateSummary( bool force = false ) { Q_UNUSED( force ); updateView(); } + + protected: + virtual bool eventFilter( QObject *obj, QEvent* e ); + + private slots: + void updateView(); + void popupMenu( const QString &uid ); + void viewEvent( const QString &uid ); + void removeEvent( const QString &uid ); + + private: + KOrganizerPlugin *mPlugin; + QGridLayout *mLayout; + + QPtrList<QLabel> mLabels; + KCal::CalendarResources *mCalendar; +}; + +#endif diff --git a/kontact/plugins/korganizer/todoplugin.cpp b/kontact/plugins/korganizer/todoplugin.cpp new file mode 100644 index 000000000..4cb281b84 --- /dev/null +++ b/kontact/plugins/korganizer/todoplugin.cpp @@ -0,0 +1,230 @@ +/* + This file is part of Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qwidget.h> +#include <qdragobject.h> +#include <qfile.h> + +#include <kapplication.h> +#include <kabc/vcardconverter.h> +#include <kaction.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <dcopclient.h> +#include <dcopref.h> +#include <ktempfile.h> + +#include <libkcal/calendarlocal.h> +#include <libkcal/icaldrag.h> + +#include <libkdepim/maillistdrag.h> +#include <libkdepim/kvcarddrag.h> +#include <libkdepim/kpimprefs.h> + +#include "core.h" + +#include "todoplugin.h" +#include "todosummarywidget.h" +#include "korg_uniqueapp.h" + +typedef KGenericFactory< TodoPlugin, Kontact::Core > TodoPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_todoplugin, + TodoPluginFactory( "kontact_todoplugin" ) ) + +TodoPlugin::TodoPlugin( Kontact::Core *core, const char *, const QStringList& ) + : Kontact::Plugin( core, core, "korganizer" ), + mIface( 0 ) +{ + setInstance( TodoPluginFactory::instance() ); + instance()->iconLoader()->addAppDir("kdepim"); + + insertNewAction( new KAction( i18n( "New To-do..." ), "newtodo", + CTRL+SHIFT+Key_T, this, SLOT( slotNewTodo() ), actionCollection(), + "new_todo" ) ); + + insertSyncAction( new KAction( i18n( "Synchronize To-do List" ), "reload", + 0, this, SLOT( slotSyncTodos() ), actionCollection(), + "todo_sync" ) ); + + mUniqueAppWatcher = new Kontact::UniqueAppWatcher( + new Kontact::UniqueAppHandlerFactory<KOrganizerUniqueAppHandler>(), this ); +} + +TodoPlugin::~TodoPlugin() +{ +} + +Kontact::Summary *TodoPlugin::createSummaryWidget( QWidget *parent ) +{ + return new TodoSummaryWidget( this, parent ); +} + +KParts::ReadOnlyPart *TodoPlugin::createPart() +{ + KParts::ReadOnlyPart *part = loadPart(); + + if ( !part ) + return 0; + + dcopClient(); // ensure that we register to DCOP as "korganizer" + mIface = new KCalendarIface_stub( dcopClient(), "kontact", "CalendarIface" ); + + return part; +} + +void TodoPlugin::select() +{ + interface()->showTodoView(); +} + +QStringList TodoPlugin::invisibleToolbarActions() const +{ + QStringList invisible; + invisible += "new_event"; + invisible += "new_todo"; + invisible += "new_journal"; + + invisible += "view_day"; + invisible += "view_list"; + invisible += "view_workweek"; + invisible += "view_week"; + invisible += "view_nextx"; + invisible += "view_month"; + invisible += "view_journal"; + return invisible; +} + +KCalendarIface_stub *TodoPlugin::interface() +{ + if ( !mIface ) { + part(); + } + Q_ASSERT( mIface ); + return mIface; +} + +void TodoPlugin::slotNewTodo() +{ + interface()->openTodoEditor( "" ); +} + +void TodoPlugin::slotSyncTodos() +{ + DCOPRef ref( "kmail", "KMailICalIface" ); + ref.send( "triggerSync", QString("Todo") ); +} + +bool TodoPlugin::createDCOPInterface( const QString& serviceType ) +{ + kdDebug(5602) << k_funcinfo << serviceType << endl; + if ( serviceType == "DCOP/Organizer" || serviceType == "DCOP/Calendar" ) { + if ( part() ) + return true; + } + + return false; +} + +bool TodoPlugin::canDecodeDrag( QMimeSource *mimeSource ) +{ + return QTextDrag::canDecode( mimeSource ) || + KPIM::MailListDrag::canDecode( mimeSource ); +} + +bool TodoPlugin::isRunningStandalone() +{ + return mUniqueAppWatcher->isRunningStandalone(); +} + +void TodoPlugin::processDropEvent( QDropEvent *event ) +{ + QString text; + + KABC::VCardConverter converter; + if ( KVCardDrag::canDecode( event ) && KVCardDrag::decode( event, text ) ) { + KABC::Addressee::List contacts = converter.parseVCards( text ); + KABC::Addressee::List::Iterator it; + + QStringList attendees; + for ( it = contacts.begin(); it != contacts.end(); ++it ) { + QString email = (*it).fullEmail(); + if ( email.isEmpty() ) + attendees.append( (*it).realName() + "<>" ); + else + attendees.append( email ); + } + + interface()->openTodoEditor( i18n( "Meeting" ), QString::null, QString::null, + attendees ); + return; + } + + if ( KCal::ICalDrag::canDecode( event) ) { + KCal::CalendarLocal cal( KPimPrefs::timezone() ); + if ( KCal::ICalDrag::decode( event, &cal ) ) { + KCal::Journal::List journals = cal.journals(); + if ( !journals.isEmpty() ) { + event->accept(); + KCal::Journal *j = journals.first(); + interface()->openTodoEditor( i18n("Note: %1").arg( j->summary() ), j->description(), QString() ); + return; + } + // else fall through to text decoding + } + } + + if ( QTextDrag::decode( event, text ) ) { + interface()->openTodoEditor( text ); + return; + } + + KPIM::MailList mails; + if ( KPIM::MailListDrag::decode( event, mails ) ) { + if ( mails.count() != 1 ) { + KMessageBox::sorry( core(), + i18n("Drops of multiple mails are not supported." ) ); + } else { + KPIM::MailSummary mail = mails.first(); + QString txt = i18n("From: %1\nTo: %2\nSubject: %3").arg( mail.from() ) + .arg( mail.to() ).arg( mail.subject() ); + + KTempFile tf; + tf.setAutoDelete( true ); + QString uri = "kmail:" + QString::number( mail.serialNumber() ) + "/" + + mail.messageId(); + tf.file()->writeBlock( event->encodedData( "message/rfc822" ) ); + tf.close(); + interface()->openTodoEditor( i18n("Mail: %1").arg( mail.subject() ), txt, + uri, tf.name(), QStringList(), "message/rfc822" ); + } + return; + } + + KMessageBox::sorry( core(), i18n("Cannot handle drop events of type '%1'.") + .arg( event->format() ) ); +} + +#include "todoplugin.moc" diff --git a/kontact/plugins/korganizer/todoplugin.desktop b/kontact/plugins/korganizer/todoplugin.desktop new file mode 100644 index 000000000..a571539d8 --- /dev/null +++ b/kontact/plugins/korganizer/todoplugin.desktop @@ -0,0 +1,65 @@ +[Desktop Entry] +Type=Service +Icon=kontact_todo +ServiceTypes=Kontact/Plugin + +X-KDE-Library=libkontact_todoplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPartLibraryName=libkorganizerpart +X-KDE-KontactPartExecutableName=korganizer +X-KDE-KontactPluginHasSummary=true + +X-KDE-PluginInfo-Website=http://korganizer.kde.org +X-KDE-PluginInfo-Name=kontact_todoplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=To-do List Component (KOrganizer plugin) +Comment[bg]=Приставка за KOrganizer +Comment[ca]=Component de llista de pendents (endollable del KOrganizer) +Comment[da]=Komponent til gøremålsliste (KOrganizer-plugin) +Comment[de]=Aufgabenlisten-Komponente (KOrganizer-Modul) +Comment[el]=Συστατικό λίστα προς υλοποίηση εργασιών (Πρόσθετο του KOrganizer) +Comment[es]=Componente de tareas pendientes (complemento de KOrganizer) +Comment[et]=Ülesannete nimekirja plugin (KOrganizer) +Comment[fr]=Composant de la liste des tâches (Module KOrganizer) +Comment[is]=Verkefnaeining (KOrganizer íforrit) +Comment[it]=Componente elenco delle cose da fare (plugin KOrganizer) +Comment[ja]=To-Do リストコンポーネント (KOrganizer プラグイン) +Comment[km]=សមាសភាគបញ្ជីការងារត្រូវធ្វើ (កម្មវិធីជំនួយ KOrganizer) +Comment[nds]=Opgavenlist-Komponent (KOrganizer-Moduul) +Comment[nl]=Takenlijstcomponent (KOrganizer-plugin) +Comment[pl]=Składnik zadań (wtyczka KOrganizer) +Comment[ru]=Задачи (модуль KOrganizer) +Comment[sk]=Komponent zoznamu úloh (Modul pre KOrganizer) +Comment[sr]=Прикључак листе обавеза (прикључак KOrganizer-а) +Comment[sr@Latn]=Priključak liste obaveza (priključak KOrganizer-a) +Comment[sv]=Uppgiftslistkomponent (Korganizer-insticksprogram) +Comment[tr]=Yapılacak İşler Bileşeni (KOrganizer eklentisi) +Comment[zh_CN]=待办清单组件(KOrganizer 插件) +Comment[zh_TW]=待辦事項清單組件(KOrganizer 外掛程式) +Name=To-do +Name[bg]=Задачи +Name[ca]=Pendents +Name[da]=Gøremål +Name[de]=Aufgaben +Name[el]=Προς υλοποίηση εργασίες +Name[es]=Tareas pendientes +Name[et]=Ülesanded +Name[fr]=Tâches +Name[is]=Verkefni +Name[it]=Cose da fare +Name[ja]=To-Do +Name[km]=ការងារត្រូវធ្វើ +Name[nds]=Opgaav +Name[nl]=Takenlijst +Name[pl]=Lista zadań +Name[ru]=Задачи +Name[sk]=Zoznam úloh +Name[sr]=Обавезе +Name[sr@Latn]=Obaveze +Name[sv]=Uppgift +Name[tr]=Yapılacak Ögeleri +Name[zh_CN]=待办清单 +Name[zh_TW]=待辦事項 diff --git a/kontact/plugins/korganizer/todoplugin.h b/kontact/plugins/korganizer/todoplugin.h new file mode 100644 index 000000000..ce0cb5823 --- /dev/null +++ b/kontact/plugins/korganizer/todoplugin.h @@ -0,0 +1,68 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef KONTACT_TODOPLUGIN_H +#define KONTACT_TODOPLUGIN_H + +#include <klocale.h> +#include <kparts/part.h> + +#include "kcalendariface_stub.h" +#include "plugin.h" +#include "uniqueapphandler.h" + +class TodoPlugin : public Kontact::Plugin +{ + Q_OBJECT + public: + TodoPlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~TodoPlugin(); + + virtual bool createDCOPInterface( const QString& serviceType ); + virtual bool isRunningStandalone(); + int weight() const { return 450; } + + bool canDecodeDrag( QMimeSource * ); + void processDropEvent( QDropEvent * ); + + virtual QStringList invisibleToolbarActions() const; + + virtual Kontact::Summary *createSummaryWidget( QWidget *parent ); + + void select(); + + KCalendarIface_stub *interface(); + + protected: + KParts::ReadOnlyPart *createPart(); + + private slots: + void slotNewTodo(); + void slotSyncTodos(); + + private: + KCalendarIface_stub *mIface; + Kontact::UniqueAppWatcher *mUniqueAppWatcher; +}; + +#endif diff --git a/kontact/plugins/korganizer/todosummarywidget.cpp b/kontact/plugins/korganizer/todosummarywidget.cpp new file mode 100644 index 000000000..d52941ee4 --- /dev/null +++ b/kontact/plugins/korganizer/todosummarywidget.cpp @@ -0,0 +1,270 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qcursor.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> + +#include <kdialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kparts/part.h> +#include <kpopupmenu.h> +#include <kstandarddirs.h> +#include <kurllabel.h> +#include <libkcal/resourcecalendar.h> +#include <libkcal/resourcelocal.h> +#include <libkcal/todo.h> +#include <libkcal/incidenceformatter.h> +#include <libkdepim/kpimprefs.h> + +#include "korganizeriface_stub.h" + +#include "core.h" +#include "plugin.h" +#include "todoplugin.h" + +#include "korganizer/stdcalendar.h" +#include "korganizer/koglobals.h" +#include "korganizer/incidencechanger.h" + +#include "todosummarywidget.h" + +TodoSummaryWidget::TodoSummaryWidget( TodoPlugin *plugin, + QWidget *parent, const char *name ) + : Kontact::Summary( parent, name ), mPlugin( plugin ) +{ + QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 ); + + QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_todo", + KIcon::Desktop, KIcon::SizeMedium ); + QWidget *header = createHeader( this, icon, i18n( "To-do" ) ); + mainLayout->addWidget( header ); + + mLayout = new QGridLayout( mainLayout, 7, 4, 3 ); + mLayout->setRowStretch( 6, 1 ); + + mCalendar = KOrg::StdCalendar::self(); + mCalendar->load(); + + connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) ); + connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ), + SLOT( updateView() ) ); + + updateView(); +} + +TodoSummaryWidget::~TodoSummaryWidget() +{ +} + +void TodoSummaryWidget::updateView() +{ + mLabels.setAutoDelete( true ); + mLabels.clear(); + mLabels.setAutoDelete( false ); + + KConfig config( "kcmkorgsummaryrc" ); + config.setGroup( "Todo" ); + bool showAllTodos = config.readBoolEntry( "ShowAllTodos", false ); + + KIconLoader loader( "kdepim" ); + + QLabel *label = 0; + int counter = 0; + + QDate currentDate = QDate::currentDate(); + KCal::Todo::List todos = mCalendar->todos(); + if ( todos.count() > 0 ) { + QPixmap pm = loader.loadIcon( "todo", KIcon::Small ); + KCal::Todo::List::ConstIterator it; + for ( it = todos.begin(); it != todos.end(); ++it ) { + KCal::Todo *todo = *it; + + bool accepted = false; + QString stateText; + + // show all incomplete todos + if ( showAllTodos && !todo->isCompleted()) + accepted = true; + + // show uncomplete todos from the last days + if ( todo->hasDueDate() && !todo->isCompleted() && + todo->dtDue().date() < currentDate ) { + accepted = true; + stateText = i18n( "overdue" ); + } + + // show todos which started somewhere in the past and has to be finished in future + if ( todo->hasStartDate() && todo->hasDueDate() && + todo->dtStart().date() < currentDate && + currentDate < todo->dtDue().date() ) { + accepted = true; + stateText = i18n( "in progress" ); + } + + // all todos which start today + if ( todo->hasStartDate() && todo->dtStart().date() == currentDate ) { + accepted = true; + stateText = i18n( "starts today" ); + } + + // all todos which end today + if ( todo->hasDueDate() && todo->dtDue().date() == currentDate ) { + accepted = true; + stateText = i18n( "ends today" ); + } + + if ( !accepted ) + continue; + + label = new QLabel( this ); + label->setPixmap( pm ); + label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + mLayout->addWidget( label, counter, 0 ); + mLabels.append( label ); + + label = new QLabel( QString::number( todo->percentComplete() ) + "%", this ); + label->setAlignment( AlignHCenter | AlignVCenter ); + label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + mLayout->addWidget( label, counter, 1 ); + mLabels.append( label ); + + QString sSummary = todo->summary(); + if ( todo->relatedTo() ) { // show parent only, not entire ancestry + sSummary = todo->relatedTo()->summary() + ":" + todo->summary(); + } + KURLLabel *urlLabel = new KURLLabel( this ); + urlLabel->setText( sSummary ); + urlLabel->setURL( todo->uid() ); + urlLabel->installEventFilter( this ); + urlLabel->setTextFormat( Qt::RichText ); + mLayout->addWidget( urlLabel, counter, 2 ); + mLabels.append( urlLabel ); + + connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + this, SLOT( viewTodo( const QString& ) ) ); + connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ), + this, SLOT( popupMenu( const QString& ) ) ); + + QString tipText( KCal::IncidenceFormatter::toolTipString( todo, true ) ); + if ( !tipText.isEmpty() ) { + QToolTip::add( urlLabel, tipText ); + } + + label = new QLabel( stateText, this ); + label->setAlignment( AlignLeft | AlignVCenter ); + label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); + mLayout->addWidget( label, counter, 3 ); + mLabels.append( label ); + + counter++; + } + } + + if ( counter == 0 ) { + QLabel *noTodos = new QLabel( i18n( "No to-dos pending" ), this ); + noTodos->setAlignment( AlignHCenter | AlignVCenter ); + mLayout->addWidget( noTodos, 0, 1 ); + mLabels.append( noTodos ); + } + + for ( label = mLabels.first(); label; label = mLabels.next() ) + label->show(); +} + +void TodoSummaryWidget::viewTodo( const QString &uid ) +{ + mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded + KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" ); + iface.editIncidence( uid ); +} + +void TodoSummaryWidget::removeTodo( const QString &uid ) +{ + mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded + KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" ); + iface.deleteIncidence( uid, false ); +} + +void TodoSummaryWidget::completeTodo( const QString &uid ) +{ + KCal::Todo *todo = mCalendar->todo( uid ); + IncidenceChanger *changer = new IncidenceChanger( mCalendar, this ); + if ( !todo->isReadOnly() && changer->beginChange( todo ) ) { + KCal::Todo *oldTodo = todo->clone(); + todo->setCompleted( QDateTime::currentDateTime() ); + changer->changeIncidence( oldTodo, todo, KOGlobals::COMPLETION_MODIFIED ); + changer->endChange( todo ); + delete oldTodo; + updateView(); + } +} + +void TodoSummaryWidget::popupMenu( const QString &uid ) +{ + KPopupMenu popup( this ); + QToolTip::remove( this ); + popup.insertItem( i18n( "&Edit To-do..." ), 0 ); + popup.insertItem( KGlobal::iconLoader()->loadIcon( "editdelete", KIcon::Small), + i18n( "&Delete To-do" ), 1 ); + KCal::Todo *todo = mCalendar->todo( uid ); + if ( !todo->isCompleted() ) { + popup.insertItem( KGlobal::iconLoader()->loadIcon( "checkedbox", KIcon::Small), + i18n( "&Mark To-do Completed" ), 2 ); + } + + switch ( popup.exec( QCursor::pos() ) ) { + case 0: + viewTodo( uid ); + break; + case 1: + removeTodo( uid ); + break; + case 2: + completeTodo( uid ); + break; + } +} + +bool TodoSummaryWidget::eventFilter( QObject *obj, QEvent* e ) +{ + if ( obj->inherits( "KURLLabel" ) ) { + KURLLabel* label = static_cast<KURLLabel*>( obj ); + if ( e->type() == QEvent::Enter ) + emit message( i18n( "Edit To-do: \"%1\"" ).arg( label->text() ) ); + if ( e->type() == QEvent::Leave ) + emit message( QString::null ); + } + + return Kontact::Summary::eventFilter( obj, e ); +} + +QStringList TodoSummaryWidget::configModules() const +{ + return QStringList( "kcmtodosummary.desktop" ); +} + +#include "todosummarywidget.moc" diff --git a/kontact/plugins/korganizer/todosummarywidget.h b/kontact/plugins/korganizer/todosummarywidget.h new file mode 100644 index 000000000..d5aca429e --- /dev/null +++ b/kontact/plugins/korganizer/todosummarywidget.h @@ -0,0 +1,72 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef TODO_SUMMARYWIDGET_H +#define TODO_SUMMARYWIDGET_H + +#include <qptrlist.h> +#include <qwidget.h> + +#include <libkcal/calendarresources.h> + +#include "summary.h" + +class QGridLayout; +class QLabel; + +class TodoPlugin; + +class TodoSummaryWidget : public Kontact::Summary +{ + Q_OBJECT + + public: + TodoSummaryWidget( TodoPlugin *plugin, QWidget *parent, + const char *name = 0 ); + ~TodoSummaryWidget(); + + int summaryHeight() const { return 3; } + QStringList configModules() const; + + public slots: + void updateSummary( bool force = false ) { Q_UNUSED( force ); updateView(); } + + protected: + virtual bool eventFilter( QObject *obj, QEvent* e ); + + private slots: + void updateView(); + void popupMenu( const QString &uid ); + void viewTodo( const QString &uid ); + void removeTodo( const QString &uid ); + void completeTodo( const QString &uid ); + + private: + TodoPlugin *mPlugin; + QGridLayout *mLayout; + + QPtrList<QLabel> mLabels; + KCal::CalendarResources *mCalendar; +}; + +#endif diff --git a/kontact/plugins/kpilot/Makefile.am b/kontact/plugins/kpilot/Makefile.am new file mode 100644 index 000000000..2383a4fbd --- /dev/null +++ b/kontact/plugins/kpilot/Makefile.am @@ -0,0 +1,24 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces \ + -I$(top_srcdir)/libkdepim \ + -I$(top_srcdir) \ + -I$(top_srcdir)/kpilot/lib \ + -I$(top_srcdir)/kpilot/kpilot \ + $(PISOCK_INCLUDE) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_kpilotplugin.la +libkontact_kpilotplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_kpilotplugin_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la \ + $(LIB_KPARTS) \ + $(top_builddir)/libkdepim/libkdepim.la \ + $(top_builddir)/kpilot/lib/libkpilot.la + +libkontact_kpilotplugin_la_SOURCES = kpilot_plugin.cpp summarywidget.cpp \ + summarywidget.skel pilotDaemonDCOP.stub + +pilotDaemonDCOP_DIR = $(top_srcdir)/kpilot/kpilot +pilotDaemonDCOP_DCOPIDLNG = true + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = kpilotplugin.desktop diff --git a/kontact/plugins/kpilot/kpilot_plugin.cpp b/kontact/plugins/kpilot/kpilot_plugin.cpp new file mode 100644 index 000000000..ed6104bd4 --- /dev/null +++ b/kontact/plugins/kpilot/kpilot_plugin.cpp @@ -0,0 +1,69 @@ +/* + This file is part of Kontact. + Copyright (C) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 "options.h" + +#include <kaboutdata.h> +#include <kgenericfactory.h> +#include <kparts/componentfactory.h> + +#include "core.h" +#include "summarywidget.h" + +#include "kpilot_plugin.h" + +typedef KGenericFactory< KPilotPlugin, Kontact::Core > KPilotPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_kpilotplugin, + KPilotPluginFactory( "kontact_kpilotplugin" ) ) + +KPilotPlugin::KPilotPlugin( Kontact::Core *core, const char *name, const QStringList& ) + : Kontact::Plugin( core, core, "kpilot" ), mAboutData( 0 ) +{ + setInstance( KPilotPluginFactory::instance() ); + // TODO: Make sure kpilotDaemon is running! + + +} + +Kontact::Summary *KPilotPlugin::createSummaryWidget( QWidget *parentWidget ) +{ + return new SummaryWidget( parentWidget ); +} + +const KAboutData *KPilotPlugin::aboutData() +{ + if ( !mAboutData ) { + mAboutData = new KAboutData("kpilotplugin", I18N_NOOP("KPilot Information"), + KPILOT_VERSION, + I18N_NOOP("KPilot - HotSync software for KDE\n\n"), + KAboutData::License_GPL, "(c) 2004 Reinhold Kainhofer"); + mAboutData->addAuthor("Reinhold Kainhofer", + I18N_NOOP("Plugin Developer"), "reinhold@kainhofer.com", "http://reinhold.kainhofer.com/Linux/"); + mAboutData->addAuthor("Dan Pilone", + I18N_NOOP("Project Leader"), + 0, "http://www.kpilot.org/"); + mAboutData->addAuthor("Adriaan de Groot", + I18N_NOOP("Maintainer"), + "groot@kde.org", "http://people.fruitsalad.org/adridg/"); + } + + return mAboutData; +} diff --git a/kontact/plugins/kpilot/kpilot_plugin.h b/kontact/plugins/kpilot/kpilot_plugin.h new file mode 100644 index 000000000..9b76bd644 --- /dev/null +++ b/kontact/plugins/kpilot/kpilot_plugin.h @@ -0,0 +1,49 @@ +/* + This file is part of Kontact. + Copyright (C) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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 KPilot_PLUGIN_H +#define KPilot_PLUGIN_H + +#include "plugin.h" +#include "pilotDaemonDCOP_stub.h" + +class SummaryWidget; + +class KPilotPlugin : public Kontact::Plugin +{ + public: + KPilotPlugin( Kontact::Core *core, const char *name, const QStringList& ); + KPilotPlugin(); + + virtual Kontact::Summary *createSummaryWidget( QWidget *parentWidget ); + + virtual bool showInSideBar() const { return false; } +// virtual QStringList configModules() const; + + const KAboutData *aboutData(); + + protected: + virtual KParts::ReadOnlyPart *createPart() { return 0; } + private: + KAboutData *mAboutData; +}; + +#endif diff --git a/kontact/plugins/kpilot/kpilotplugin.desktop b/kontact/plugins/kpilot/kpilotplugin.desktop new file mode 100644 index 000000000..7ad217fd9 --- /dev/null +++ b/kontact/plugins/kpilot/kpilotplugin.desktop @@ -0,0 +1,44 @@ +[Desktop Entry] +Type=Service +Icon=kpilot +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_kpilotplugin +X-KDE-KontactIdentifier=kpilot +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPluginHasSummary=true +X-KDE-KontactPluginHasPart=false + +X-KDE-PluginInfo-Website=http://www.slac.com/~pilone/kpilot_home/ +X-KDE-PluginInfo-Name=kontact_kpilotplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Palm Tools Component (KPilot Plugin) +Comment[bg]=Приставка за KPilot +Comment[ca]=Component d'eines de la Palm (endollable del KPilot) +Comment[da]=Komponent til palm-værktøjer (KPilot-plugin) +Comment[de]=Palm-Komponente (KPilot-Modul) +Comment[el]=Συστατικό εργαλείων Palm (Πρόσθετο του KPilot) +Comment[es]=Componente de herramientas de Palm (complemento KPilot) +Comment[et]=Palmi tööriistade plugin (KPilot) +Comment[fr]=Composant d'outils pour Palms (Module KPilot) +Comment[is]=Palm verkfæraeining (KPilot íforrit) +Comment[it]=Componente strumenti Palm (plugin KPilot) +Comment[ja]=Palm ツールコンポーネント (KPilot プラグイン) +Comment[km]=សមាសភាគឧបករណ៍ Palm (កម្មវិធីជំនួយ KPilot) +Comment[nds]=Palmreekner-Warktüüchkomponent (KPilot-Moduul) +Comment[nl]=Component met hulpmiddelen voor PalmOS(tm)-apparaten (KPilot-plugin) +Comment[pl]=Składnik narzędzi Palma (wtyczka KPilot) +Comment[ru]=Синхронизация с Palm (модуль KPilot) +Comment[sr]=Компонента алата за Palm (прикључак KPilot-а) +Comment[sr@Latn]=Komponenta alata za Palm (priključak KPilot-a) +Comment[sv]=Palm Pilot-verktygskomponent (Kpilot-insticksprogram) +Comment[tr]=Palm Araçları Bileşeni (KPilot Eklentisi) +Comment[zh_CN]=Palm 工具组件(KPilot 插件) +Comment[zh_TW]=Palm 工具組件(KPilot 外掛程式) +Name=Palm +Name[nds]=Palmreekner +Name[nl]=PalmOS(tm)-apparaat +Name[sv]=Palm Pilot diff --git a/kontact/plugins/kpilot/summarywidget.cpp b/kontact/plugins/kpilot/summarywidget.cpp new file mode 100644 index 000000000..4230e6479 --- /dev/null +++ b/kontact/plugins/kpilot/summarywidget.cpp @@ -0,0 +1,242 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qimage.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qfile.h> +#include <qlabel.h> +#include <qtextedit.h> +#include <qvbox.h> + +#include <dcopclient.h> +#include <dcopref.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kurllabel.h> +#include <kdialogbase.h> +#include <kmessagebox.h> + +#include "pilotDaemonDCOP_stub.h" + +#include <ktextedit.h> + +#include "summarywidget.h" + +SummaryWidget::SummaryWidget( QWidget *parent, const char *name ) + : Kontact::Summary( parent, name ), + DCOPObject( "KPilotSummaryWidget" ), + mDCOPSuccess( false ), + mStartedDaemon( false ), + mShouldStopDaemon( true ) +{ + mLayout = new QGridLayout( this, 2, 3, 3, 3 ); + + int row=0; + QPixmap icon = KGlobal::iconLoader()->loadIcon( "kpilot", KIcon::Desktop, KIcon::SizeMedium ); + QWidget *header = createHeader( this, icon, i18n( "KPilot Configuration" ) ); + mLayout->addMultiCellWidget( header, row,row, 0,3 ); + + // Last sync information + row++; + mSyncTimeTextLabel = new QLabel( i18n( "<i>Last sync:</i>" ), this); + mLayout->addWidget( mSyncTimeTextLabel, row, 0 ); + mSyncTimeLabel = new QLabel( i18n( "No information available" ), this ); + mLayout->addWidget( mSyncTimeLabel, row, 1 ); + mShowSyncLogLabel = new KURLLabel( "", i18n( "[View Sync Log]" ), this ); + mLayout->addWidget( mShowSyncLogLabel, row, 3 ); + connect( mShowSyncLogLabel, SIGNAL( leftClickedURL( const QString& ) ), + this, SLOT( showSyncLog( const QString& ) ) ); + + // User + row++; + mPilotUserTextLabel = new QLabel( i18n( "<i>User:</i>" ), this); + mLayout->addWidget( mPilotUserTextLabel, row, 0); + mPilotUserLabel = new QLabel( i18n( "Unknown" ), this ); + mLayout->addMultiCellWidget( mPilotUserLabel, row, row, 1, 3 ); + + // Device information + row++; + mPilotDeviceTextLabel = new QLabel( i18n( "<i>Device:</i>" ), this); + mLayout->addWidget( mPilotDeviceTextLabel, row, 0 ); + mPilotDeviceLabel = new QLabel( i18n( "Unknown" ), this ); + mLayout->addMultiCellWidget( mPilotDeviceLabel, row, row, 1, 3 ); + + // Status + row++; + mDaemonStatusTextLabel = new QLabel( i18n( "<i>Status:</i>" ), this); + mLayout->addWidget( mDaemonStatusTextLabel, row, 0 ); + mDaemonStatusLabel = new QLabel( i18n( "No communication with the daemon possible" ), this ); + mLayout->addMultiCellWidget( mDaemonStatusLabel, row, row, 1, 3 ); + + // Conduits: + row++; + mConduitsTextLabel = new QLabel( i18n( "<i>Conduits:</i>" ), this ); + mConduitsTextLabel->setAlignment( AlignAuto | AlignTop | ExpandTabs ); + mLayout->addWidget( mConduitsTextLabel, row, 0 ); + mConduitsLabel = new QLabel( i18n( "No information available" ), this ); + mConduitsLabel->setAlignment( mConduitsLabel->alignment() | Qt::WordBreak ); + mLayout->addMultiCellWidget( mConduitsLabel, row, row, 1, 3 ); + + // widgets shown if kpilotDaemon is not running + row++; + mNoConnectionLabel = new QLabel( i18n( "KPilot is currently not running." ), this ); + mLayout->addMultiCellWidget( mNoConnectionLabel, row, row, 1, 2 ); + mNoConnectionStartLabel = new KURLLabel( "", i18n( "[Start KPilot]" ), this ); + mLayout->addWidget( mNoConnectionStartLabel, row, 3 ); + connect( mNoConnectionStartLabel, SIGNAL( leftClickedURL( const QString& ) ), + this, SLOT( startKPilot() ) ); + + if ( !kapp->dcopClient()->isApplicationRegistered( "kpilotDaemon" ) ) { + startKPilot(); + } + + connectDCOPSignal( 0, 0, "kpilotDaemonStatusDetails(QDateTime,QString,QStringList,QString,QString,QString,bool)", + "receiveDaemonStatusDetails(QDateTime,QString,QStringList,QString,QString,QString,bool)", false ); + connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString & ) ), SLOT( slotAppRemoved( const QCString& ) ) ); +} + +SummaryWidget::~SummaryWidget() +{ + if ( mStartedDaemon && mShouldStopDaemon ) { + PilotDaemonDCOP_stub dcopToDaemon( "kpilotDaemon", "KPilotDaemonIface" ); + dcopToDaemon.quitNow(); // ASYNC, always succeeds. + } +} + +QStringList SummaryWidget::configModules() const +{ + QStringList modules; + modules << "kpilot_config.desktop"; + return modules; +} + +void SummaryWidget::receiveDaemonStatusDetails(QDateTime lastSyncTime, QString status, QStringList conduits, QString logFileName, QString userName, QString pilotDevice, bool killOnExit ) +{ + mDCOPSuccess = true; + mLastSyncTime = lastSyncTime; + mDaemonStatus = status; + mConduits = conduits; + mSyncLog = logFileName; + mUserName = userName; + mPilotDevice = pilotDevice; + mShouldStopDaemon = killOnExit; + updateView(); +} + +void SummaryWidget::updateView() +{ + if ( mDCOPSuccess ) { + if ( mLastSyncTime.isValid() ) { + mSyncTimeLabel->setText( mLastSyncTime.toString(Qt::LocalDate) ); + } else { + mSyncTimeLabel->setText( i18n( "No information available" ) ); + } + if ( !mSyncLog.isEmpty() ) { + mShowSyncLogLabel->setEnabled( true ); + mShowSyncLogLabel->setURL( mSyncLog ); + } else { + mShowSyncLogLabel->setEnabled( false ); + } + mPilotUserLabel->setText( mUserName.isEmpty() ? i18n( "unknown" ) : mUserName ); + mPilotDeviceLabel->setText( mPilotDevice.isEmpty() ? i18n( "unknown" ) : mPilotDevice ); + mDaemonStatusLabel->setText( mDaemonStatus ); + mConduitsLabel->setText( mConduits.join( ", " ) ); + } else { + mSyncTimeLabel->setText( i18n( "No information available (Daemon not running?)" ) ); + mShowSyncLogLabel->setEnabled( false ); + mPilotUserLabel->setText( i18n( "unknown" ) ); + mPilotDeviceLabel->setText( i18n( "unknown" ) ); + mDaemonStatusLabel->setText( i18n( "No communication with the daemon possible" ) ); + mConduitsLabel->setText( i18n( "No information available" ) ); + } + + mSyncTimeTextLabel->setShown( mDCOPSuccess ); + mSyncTimeLabel->setShown( mDCOPSuccess ); + mShowSyncLogLabel->setShown( mDCOPSuccess ); + mPilotUserTextLabel->setShown( mDCOPSuccess ); + mPilotUserLabel->setShown( mDCOPSuccess ); + mPilotDeviceTextLabel->setShown( mDCOPSuccess ); + mPilotDeviceLabel->setShown( mDCOPSuccess ); + mDaemonStatusTextLabel->setShown( mDCOPSuccess ); + mDaemonStatusLabel->setShown( mDCOPSuccess ); + mConduitsTextLabel->setShown( mDCOPSuccess ); + mConduitsLabel->setShown( mDCOPSuccess ); + mNoConnectionLabel->setShown( !mDCOPSuccess ); + mNoConnectionStartLabel->setShown( !mDCOPSuccess ); +} + +void SummaryWidget::showSyncLog( const QString &filename ) +{ + KDialogBase dlg( this, 0, true, QString::null, KDialogBase::Ok, KDialogBase::Ok ); + dlg.setCaption( i18n( "KPilot HotSync Log" ) ); + + QTextEdit *edit = new QTextEdit( dlg.makeVBoxMainWidget() ); + edit->setReadOnly( true ); + + QFile f(filename); + if ( !f.open( IO_ReadOnly ) ) { + KMessageBox::error( this, i18n( "Unable to open Hotsync log %1." ).arg( filename ) ); + return; + } + + QTextStream s( &f ); + while ( !s.eof() ) + edit->append( s.readLine() ); + + edit->moveCursor( QTextEdit::MoveHome, false ); + + f.close(); + + dlg.setInitialSize( QSize( 400, 350 ) ); + dlg.exec(); +} + +void SummaryWidget::startKPilot() +{ + QString error; + QCString appID; + if ( !KApplication::kdeinitExec( "kpilotDaemon", QString( "--fail-silently" ) ) ) { + kdDebug(5602) << "No service available..." << endl; + mStartedDaemon = true; + } +} + +void SummaryWidget::slotAppRemoved( const QCString & appId ) +{ + if ( appId == "kpilotDaemon" ) + { + mDCOPSuccess = false; + updateView(); + } +} + + +#include "summarywidget.moc" + diff --git a/kontact/plugins/kpilot/summarywidget.h b/kontact/plugins/kpilot/summarywidget.h new file mode 100644 index 000000000..94fda7e55 --- /dev/null +++ b/kontact/plugins/kpilot/summarywidget.h @@ -0,0 +1,99 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SUMMARYWIDGET_H +#define SUMMARYWIDGET_H + +#include "summary.h" + +#include <dcopobject.h> +#include <pilotDaemonDCOP.h> + +#include <qmap.h> +#include <qpixmap.h> +#include <qptrlist.h> +#include <qstringlist.h> +#include <qtimer.h> +#include <qwidget.h> +#include <qdatetime.h> + +class QGridLayout; +class QLabel; +class KURLLabel; + +class SummaryWidget : public Kontact::Summary, public DCOPObject +{ + Q_OBJECT + K_DCOP + + public: + SummaryWidget( QWidget *parent, const char *name = 0 ); + virtual ~SummaryWidget(); + + int summaryHeight() const { return 1; } + + QStringList configModules() const; + + k_dcop: + // all the information is pushed to Kontact by the daemon, to remove the chance of Kontact calling a daemon + // that is blocked for some reason, and blocking itself. + void receiveDaemonStatusDetails( QDateTime, QString, QStringList, QString, QString, QString, bool ); + private slots: + void updateView(); + void showSyncLog( const QString &filename ); + void startKPilot(); + void slotAppRemoved( const QCString & ); + private: + QTimer mTimer; + + QLabel*mSyncTimeTextLabel; + QLabel*mSyncTimeLabel; + KURLLabel*mShowSyncLogLabel; + QLabel*mPilotUserTextLabel; + QLabel*mPilotUserLabel; + QLabel*mPilotDeviceTextLabel; + QLabel*mPilotDeviceLabel; + QLabel*mDaemonStatusTextLabel; + QLabel*mDaemonStatusLabel; + QLabel*mConduitsTextLabel; + QLabel*mConduitsLabel; + QLabel*mNoConnectionLabel; + KURLLabel*mNoConnectionStartLabel; + + QGridLayout *mLayout; + + QDateTime mLastSyncTime; + QString mDaemonStatus; + QStringList mConduits; + QString mSyncLog; + QString mUserName; + QString mPilotDevice; + bool mDCOPSuccess; + + bool mStartedDaemon; // Record whether the daemon was started by kontact + bool mShouldStopDaemon; +}; + +#endif + diff --git a/kontact/plugins/newsticker/Makefile.am b/kontact/plugins/newsticker/Makefile.am new file mode 100644 index 000000000..779936802 --- /dev/null +++ b/kontact/plugins/newsticker/Makefile.am @@ -0,0 +1,26 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces \ + -I$(top_srcdir)/libkdepim \ + -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_newstickerplugin.la kcm_kontactknt.la +libkontact_newstickerplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_newstickerplugin_la_LIBADD = $(LIB_KPARTS) $(LIB_KDEUI) \ + $(top_builddir)/libkdepim/libkdepim.la ../../interfaces/libkpinterfaces.la + +libkontact_newstickerplugin_la_SOURCES = newsticker_plugin.cpp \ + summarywidget.cpp summarywidget.skel + +kcm_kontactknt_la_SOURCES = kcmkontactknt.cpp +kcm_kontactknt_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) \ + -avoid-version -no-undefined +kcm_kontactknt_la_LIBADD = $(LIB_KDEUI) + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = newstickerplugin.desktop + +kde_services_DATA = kcmkontactknt.desktop + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kcmkontactnt.pot diff --git a/kontact/plugins/newsticker/kcmkontactknt.cpp b/kontact/plugins/newsticker/kcmkontactknt.cpp new file mode 100644 index 000000000..18f439c8e --- /dev/null +++ b/kontact/plugins/newsticker/kcmkontactknt.cpp @@ -0,0 +1,452 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qgroupbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qvaluevector.h> +#include <qspinbox.h> + +#include <dcopref.h> +#include <dcopclient.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kaccelmanager.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <klistview.h> +#include <klocale.h> +#include <kpushbutton.h> + +#include "kcmkontactknt.h" + +#include "newsfeeds.h" + +#include <kdepimmacros.h> + +extern "C" +{ + KDE_EXPORT KCModule *create_kontactknt( QWidget *parent, const char * ) + { + return new KCMKontactKNT( parent, "kcmkontactknt" ); + } +} + +NewsEditDialog::NewsEditDialog( const QString& title, const QString& url, QWidget *parent ) + : KDialogBase( Plain, i18n( "New News Feed" ), Ok | Cancel, + Ok, parent, 0, true, true ) +{ + QWidget *page = plainPage(); + QGridLayout *layout = new QGridLayout( page, 2, 3, marginHint(), + spacingHint() ); + + QLabel *label = new QLabel( i18n( "Name:" ), page ); + layout->addWidget( label, 0, 0 ); + + mTitle = new QLineEdit( page ); + label->setBuddy( mTitle ); + layout->addMultiCellWidget( mTitle, 0, 0, 1, 2 ); + + label = new QLabel( i18n( "URL:" ), page ); + layout->addWidget( label, 1, 0 ); + + mURL = new QLineEdit( page ); + label->setBuddy( mURL ); + layout->addMultiCellWidget( mURL, 1, 1, 1, 2 ); + + mTitle->setText( title ); + mURL->setText( url ); + mTitle->setFocus(); + connect( mTitle, SIGNAL( textChanged( const QString& ) ), + this, SLOT( modified() ) ); + connect( mURL, SIGNAL( textChanged( const QString& ) ), + this, SLOT( modified() ) ); + + modified(); +} + +void NewsEditDialog::modified() +{ + enableButton( KDialogBase::Ok, !title().isEmpty() && !url().isEmpty() ); +} + +QString NewsEditDialog::title() const +{ + return mTitle->text(); +} + +QString NewsEditDialog::url() const +{ + return mURL->text(); +} + +class NewsItem : public QListViewItem +{ + public: + NewsItem( QListView *parent, const QString& title, const QString& url, bool custom ) + : QListViewItem( parent ), mTitle( title ), mUrl( url ), mCustom( custom ) + { + setText( 0, mTitle ); + } + + NewsItem( QListViewItem *parent, const QString& title, const QString& url, bool custom ) + : QListViewItem( parent ), mTitle( title ), mUrl( url ), mCustom( custom ) + { + setText( 0, mTitle ); + } + + QString title() const { return mTitle; } + QString url() const { return mUrl; } + bool custom() const { return mCustom; } + + private: + QString mTitle; + QString mUrl; + bool mCustom; +}; + +KCMKontactKNT::KCMKontactKNT( QWidget *parent, const char *name ) + : KCModule( parent, name ) +{ + initGUI(); + + connect( mAllNews, SIGNAL( currentChanged( QListViewItem* ) ), + this, SLOT( allCurrentChanged( QListViewItem* ) ) ); + connect( mSelectedNews, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( selectedChanged( QListViewItem* ) ) ); + + connect( mUpdateInterval, SIGNAL( valueChanged( int ) ), SLOT( modified() ) ); + connect( mArticleCount, SIGNAL( valueChanged( int ) ), SLOT( modified() ) ); + + connect( mAddButton, SIGNAL( clicked() ), this, SLOT( addNews() ) ); + connect( mRemoveButton, SIGNAL( clicked() ), this, SLOT( removeNews() ) ); + connect( mNewButton, SIGNAL( clicked() ), this, SLOT( newFeed() ) ); + connect( mDeleteButton, SIGNAL( clicked() ), this, SLOT( deleteFeed() ) ); + + KAcceleratorManager::manage( this ); + + load(); +} + +void KCMKontactKNT::loadNews() +{ + QValueVector<QListViewItem*> parents; + QValueVector<QListViewItem*>::Iterator it; + + parents.append( new QListViewItem( mAllNews, i18n( "Arts" ) ) ); + parents.append( new QListViewItem( mAllNews, i18n( "Business" ) ) ); + parents.append( new QListViewItem( mAllNews, i18n( "Computers" ) ) ); + parents.append( new QListViewItem( mAllNews, i18n( "Misc" ) ) ); + parents.append( new QListViewItem( mAllNews, i18n( "Recreation" ) ) ); + parents.append( new QListViewItem( mAllNews, i18n( "Society" ) ) ); + + for ( it = parents.begin(); it != parents.end(); ++it ) + (*it)->setSelectable( false ); + + for ( int i = 0; i < DEFAULT_NEWSSOURCES; ++i ) { + NewsSourceData data = NewsSourceDefault[ i ]; + new NewsItem( parents[ data.category() ], data.name(), data.url(), false ); + mFeedMap.insert( data.url(), data.name() ); + } +} + +void KCMKontactKNT::loadCustomNews() +{ + KConfig config( "kcmkontactkntrc" ); + QMap<QString, QString> customFeeds = config.entryMap( "CustomFeeds" ); + config.setGroup( "CustomFeeds" ); + + mCustomItem = new QListViewItem( mAllNews, i18n( "Custom" ) ); + mCustomItem->setSelectable( false ); + + if ( customFeeds.count() == 0 ) + mCustomItem->setVisible( false ); + + QMap<QString, QString>::Iterator it; + for ( it = customFeeds.begin(); it != customFeeds.end(); ++it ) { + QStringList value = config.readListEntry( it.key() ); + mCustomFeeds.append( new NewsItem( mCustomItem, value[ 0 ], value[ 1 ], true ) ); + mFeedMap.insert( value[ 1 ], value[ 0 ] ); + mCustomItem->setVisible( true ); + } +} + +void KCMKontactKNT::storeCustomNews() +{ + KConfig config( "kcmkontactkntrc" ); + config.deleteGroup( "CustomFeeds" ); + config.setGroup( "CustomFeeds" ); + + int counter = 0; + QValueList<NewsItem*>::Iterator it; + for ( it = mCustomFeeds.begin(); it != mCustomFeeds.end(); ++it ) { + QStringList value; + value << (*it)->title() << (*it)->url(); + config.writeEntry( QString::number( counter ), value ); + + ++counter; + } + + config.sync(); +} + +void KCMKontactKNT::addNews() +{ + if ( !dcopActive() ) + return; + + NewsItem *item = dynamic_cast<NewsItem*>( mAllNews->selectedItem() ); + if ( item == 0 ) + return; + + DCOPRef service( "rssservice", "RSSService" ); + service.send( "add(QString)", item->url() ); + + scanNews(); + + emit changed( true ); +} + +void KCMKontactKNT::removeNews() +{ + if ( !dcopActive() ) + return; + + NewsItem *item = dynamic_cast<NewsItem*>( mSelectedNews->selectedItem() ); + if ( item == 0 ) + return; + + DCOPRef service( "rssservice", "RSSService" ); + service.send( "remove(QString)", item->url() ); + + scanNews(); + + emit changed( true ); +} + +void KCMKontactKNT::newFeed() +{ + NewsEditDialog dlg( "", "", this ); + + if ( dlg.exec() ) { + NewsItem *item = new NewsItem( mCustomItem, dlg.title(), dlg.url(), true ); + mCustomFeeds.append( item ); + mFeedMap.insert( dlg.url(), dlg.title() ); + + mCustomItem->setVisible( true ); + mCustomItem->setOpen( true ); + mAllNews->ensureItemVisible( item ); + mAllNews->setSelected( item, true ); + + emit changed( true ); + } +} + +void KCMKontactKNT::deleteFeed() +{ + NewsItem *item = dynamic_cast<NewsItem*>( mAllNews->selectedItem() ); + if ( !item ) + return; + + if ( mCustomFeeds.find( item ) == mCustomFeeds.end() ) + return; + + mCustomFeeds.remove( item ); + mFeedMap.remove( item->url() ); + delete item; + + if ( mCustomFeeds.count() == 0 ) + mCustomItem->setVisible( false ); + + emit changed( true ); +} + +void KCMKontactKNT::scanNews() +{ + if ( !dcopActive() ) + return; + + mSelectedNews->clear(); + + DCOPRef service( "rssservice", "RSSService" ); + QStringList urls = service.call( "list()" ); + + for ( uint i = 0; i < urls.count(); ++i ) + { + QString url = urls[ i ]; + QString feedName = mFeedMap[ url ]; + if ( feedName.isEmpty() ) + feedName = url; + new NewsItem( mSelectedNews, feedName, url, false ); + } +} + +void KCMKontactKNT::selectedChanged( QListViewItem *item ) +{ + mRemoveButton->setEnabled( item && item->isSelected() ); +} + +void KCMKontactKNT::allCurrentChanged( QListViewItem *item ) +{ + NewsItem *newsItem = dynamic_cast<NewsItem*>( item ); + + bool addState = false; + bool delState = false; + if ( newsItem && newsItem->isSelected() ) { + addState = true; + delState = (mCustomFeeds.find( newsItem ) != mCustomFeeds.end()); + } + + mAddButton->setEnabled( addState ); + mDeleteButton->setEnabled( delState ); +} + +void KCMKontactKNT::modified() +{ + emit changed( true ); +} + +void KCMKontactKNT::initGUI() +{ + QGridLayout *layout = new QGridLayout( this, 2, 3, KDialog::marginHint(), + KDialog::spacingHint() ); + + mAllNews = new KListView( this ); + mAllNews->addColumn( i18n( "All" ) ); + mAllNews->setRootIsDecorated( true ); + mAllNews->setFullWidth( true ); + layout->addWidget( mAllNews, 0, 0 ); + + QVBoxLayout *vbox = new QVBoxLayout( layout, KDialog::spacingHint() ); + + vbox->addStretch(); + mAddButton = new KPushButton( i18n( "Add" ), this ); + mAddButton->setEnabled( false ); + vbox->addWidget( mAddButton ); + mRemoveButton = new KPushButton( i18n( "Remove" ), this ); + mRemoveButton->setEnabled( false ); + vbox->addWidget( mRemoveButton ); + vbox->addStretch(); + + mSelectedNews = new KListView( this ); + mSelectedNews->addColumn( i18n( "Selected" ) ); + mSelectedNews->setFullWidth( true ); + layout->addWidget( mSelectedNews, 0, 2 ); + + QGroupBox *box = new QGroupBox( 0, Qt::Vertical, + i18n( "News Feed Settings" ), this ); + + QGridLayout *boxLayout = new QGridLayout( box->layout(), 2, 3, + KDialog::spacingHint() ); + + QLabel *label = new QLabel( i18n( "Refresh time:" ), box ); + boxLayout->addWidget( label, 0, 0 ); + + mUpdateInterval = new QSpinBox( 1, 3600, 1, box ); + mUpdateInterval->setSuffix( " sec." ); + label->setBuddy( mUpdateInterval ); + boxLayout->addWidget( mUpdateInterval, 0, 1 ); + + label = new QLabel( i18n( "Number of items shown:" ), box ); + boxLayout->addWidget( label, 1, 0 ); + + mArticleCount = new QSpinBox( box ); + label->setBuddy( mArticleCount ); + boxLayout->addWidget( mArticleCount, 1, 1 ); + + mNewButton = new KPushButton( i18n( "New Feed..." ), box ); + boxLayout->addWidget( mNewButton, 0, 2 ); + + mDeleteButton = new KPushButton( i18n( "Delete Feed" ), box ); + mDeleteButton->setEnabled( false ); + boxLayout->addWidget( mDeleteButton, 1, 2 ); + + layout->addMultiCellWidget( box, 1, 1, 0, 2 ); +} + +bool KCMKontactKNT::dcopActive() const +{ + QString error; + QCString appID; + bool isGood = true; + DCOPClient *client = kapp->dcopClient(); + if ( !client->isApplicationRegistered( "rssservice" ) ) { + if ( KApplication::startServiceByDesktopName( "rssservice", QStringList(), &error, &appID ) ) + isGood = false; + } + + return isGood; +} + +void KCMKontactKNT::load() +{ + mAllNews->clear(); + + loadNews(); + loadCustomNews(); + scanNews(); + + KConfig config( "kcmkontactkntrc" ); + config.setGroup( "General" ); + + mUpdateInterval->setValue( config.readNumEntry( "UpdateInterval", 600 ) ); + mArticleCount->setValue( config.readNumEntry( "ArticleCount", 4 ) ); + + emit changed( false ); +} + +void KCMKontactKNT::save() +{ + storeCustomNews(); + + KConfig config( "kcmkontactkntrc" ); + config.setGroup( "General" ); + + config.writeEntry( "UpdateInterval", mUpdateInterval->value() ); + config.writeEntry( "ArticleCount", mArticleCount->value() ); + + config.sync(); + + emit changed( false ); +} + +void KCMKontactKNT::defaults() +{ +} + +const KAboutData* KCMKontactKNT::aboutData() const +{ + KAboutData *about = new KAboutData( I18N_NOOP( "kcmkontactknt" ), + I18N_NOOP( "Newsticker Configuration Dialog" ), + 0, 0, KAboutData::License_GPL, + I18N_NOOP( "(c) 2003 - 2004 Tobias Koenig" ) ); + + about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" ); + + return about; +} + +#include "kcmkontactknt.moc" diff --git a/kontact/plugins/newsticker/kcmkontactknt.desktop b/kontact/plugins/newsticker/kcmkontactknt.desktop new file mode 100644 index 000000000..d866e252a --- /dev/null +++ b/kontact/plugins/newsticker/kcmkontactknt.desktop @@ -0,0 +1,156 @@ +[Desktop Entry] +Icon=knode +Type=Service +ServiceTypes=KCModule + +X-KDE-ModuleType=Library +X-KDE-Library=kontactknt +X-KDE-FactoryName=kontactknt +X-KDE-ParentApp=kontact_newstickerplugin +X-KDE-ParentComponents=kontact_newstickerplugin +X-KDE-CfgDlgHierarchy=KontactSummary + +Name=News Ticker +Name[af]=Nuus tikker +Name[az]=Xəbər Gözləyici +Name[br]=Kliker keleier +Name[ca]=Teletip de notícies +Name[cy]=Ticer Newyddion +Name[da]=Nyhedstelegraf +Name[de]=Newsticker +Name[el]=Προβολέας ειδήσεων +Name[eo]=Novaĵprezentilo +Name[es]=Teletipo de noticias +Name[et]=Uudistejälgija +Name[eu]=Berri markatzailea +Name[fa]=Ticker اخبار +Name[fi]=Uutisnäytin +Name[fr]=Téléscripteur de nouvelles +Name[fy]=Nijs Tikker +Name[gl]=Colector de Novas +Name[he]=חדשות רצות +Name[hi]=न्यूज टिकर +Name[hr]=Ticker sa novostima +Name[hu]=RSS hírmegjelenítő +Name[id]=Ticker Berita +Name[is]=Fréttastrimill +Name[it]=Ticker notizie +Name[ja]=ニュースティッカー +Name[ka]=სიახლეთა ტიკერი +Name[kk]=Жаңалық таспасы +Name[km]=កម្មវិធីទទួលព័ត៌មាន +Name[lt]=News pranešėjas +Name[lv]=Ziņu Tikkers +Name[ms]=Pengetik Berita +Name[nb]=Nyhetstelegraf +Name[nds]=Narichten-Ticker +Name[ne]=न्यूज टिकर +Name[nn]=Nyheitstelegraf +Name[pl]=Wiadomości +Name[pt]=Extractor de Notícias +Name[pt_BR]=Animação de Notícias +Name[ro]=Ştiri Internet +Name[ru]=Новости +Name[sk]=Sledovanie správ +Name[sl]=Prikazovalnik novic +Name[sr]=Откуцавач вести +Name[sr@Latn]=Otkucavač vesti +Name[sv]=Nyhetsövervakare +Name[ta]=செய்திகள் குறிப்பான் +Name[tg]=Ахборот +Name[th]=ตั๋วข่าว +Name[tr]=Haber İzleyici +Name[uk]=Стрічка новин +Name[ven]=Musengulusi wa Mafhungo +Name[vi]=Trình kiểm tra news +Name[xh]=Umchola-choli weendaba +Name[zh_CN]=新闻点点通 +Name[zh_TW]=新聞顯示器 +Name[zu]=Umlungiseleli Wezindaba +Comment=News Ticker Summary Setup +Comment[af]=Nuus tikker opsomming opstelling +Comment[bg]=Настройване обобщението на новините +Comment[ca]=Configuració del resum del teletip de notícies +Comment[cs]=Nastavení souhrnu newstickeru +Comment[da]=Nyhedstelegrafs opsætning af opsummering +Comment[de]=Einstellung der News-übersicht +Comment[el]=Περίληψη ρύθμισης προβολέα ρυθμίσεων +Comment[es]=Configuración del resumen del teletipo de noticias +Comment[et]=Uudistejälgija kokkuvõtte seadistus +Comment[eu]=Berri markatzailearen laburpenaren konfigurazioa +Comment[fa]=برپایی خلاصۀTicker اخبار +Comment[fi]=Uutisnäyttimen yhteenvedon asetukset +Comment[fr]=Configuration du résumé du téléscripteur de nouvelles +Comment[fy]=Oersichtsynstellings nijstikker +Comment[gl]=Configuración do Resumo de Fontes de Novas +Comment[he]=הגדרות תקציר חדשות רצות +Comment[hu]=A hírmegjelenítő áttekintőjének beállításai +Comment[is]=Uppsetning á yfirliti yfir fréttastrimla +Comment[it]=Impostazioni sommario ticker notizie +Comment[ja]=ニュースティッカーの設定 +Comment[ka]=სიახლეთა ტიკერის დაიჯესტის კონფიგურაცია +Comment[kk]=Жаңалық таспасының тұжырымынын баптау +Comment[km]=រៀបចំសេចក្ដីសង្ខេបកម្មវិធីទទួលព័ត៌មាន +Comment[lt]=News Ticker santraukos nustatymai +Comment[nb]=Oppsett av sammendraget til nyhetstelegrafen +Comment[nds]=Narichten-Översicht instellen +Comment[ne]=न्यूज टिकर सारांश सेटअप +Comment[nl]=Overzichtsinstellingen nieuwsticker +Comment[nn]=Oppsett av nyhendetelegrafsamandrag +Comment[pl]=Ustawienia podsumowania wiadomości +Comment[pt]=Configuração do Sumário do Extractor de Notícias +Comment[pt_BR]=Configuração de Resumo de Notícias +Comment[ru]=Настройка сводки новостей +Comment[sk]=Nastavenie súhrnu správ +Comment[sl]=Nastavitve povzetka novic +Comment[sr]=Подешавање сажетка приказивања вести +Comment[sr@Latn]=Podešavanje sažetka prikazivanja vesti +Comment[sv]=Inställning av nyhetsövervakningsöversikt +Comment[tr]=Haber Yakalayıcı Özet Ayarları +Comment[uk]=Налаштування зведення стрічки новин +Comment[zh_CN]=新闻点点通摘要设置 +Comment[zh_TW]=新聞顯示器摘要設定 +Keywords=news ticker, configure, settings +Keywords[bg]=новини, източник, настройки, news ticker, configure, settings +Keywords[bs]=news ticker, configure, settings, vijesti, newsticker, podešavanje +Keywords[ca]=teletip, configura, opcions +Keywords[cs]=novinky,nastavení +Keywords[da]=nyhedstelegraf, indstil, opsætning +Keywords[de]=Newsticker,Einrichten,Einstellungen +Keywords[el]=προβολέας ειδήσεων, ρύθμιση, ρυθμίσεις +Keywords[es]=teletipo de noticias, configurar, opciones +Keywords[et]=uudistejälgija, seadistamine, seadistused +Keywords[eu]=berri markatzaileak, konfiguratu, ezarpenak +Keywords[fa]=ticker اخبار، پیکربندی، تنظیمات +Keywords[fi]=uutiset, asetukset, muokkaa +Keywords[fr]=configurer,paramètre,news ticker, téléscripteur +Keywords[fy]=newsticker,instellingen,ynstellings,configuratie,nieuws,nijs +Keywords[gl]=capturador de novas, configurar, opcións +Keywords[he]=news ticker, configure, settings, חדשות, תצורה, הגדרות +Keywords[hu]=hírmegjelenítő,konfigurálás,beállítások +Keywords[is]=fréttastrimill, stillingar, stilla +Keywords[it]=ticker notizie, configura, impostazioni +Keywords[ja]=ニュースティッカー,設定,設定 +Keywords[ka]=სიახლეთა ტიკერი, კონფიგურაცია, პარამეტრები +Keywords[km]=កម្មវិធីទទួលព័ត៌មាន,កំណត់រចនាសម្ព័ន្ធ,ការកំណត់ +Keywords[lt]=news ticker, configure, settings, konfigūravimas, nustatymai, naujienų pranešėjas +Keywords[ms]=Pengetik berita, konfigur, seting +Keywords[nb]=nyhetstelegraf, oppsett, innstillinger +Keywords[nds]=Narichten-Ticker, instellen +Keywords[ne]=न्यूज टिकर, कन्फिगर, सेटिङ +Keywords[nl]=newsticker,instellingen,configuratie,nieuws +Keywords[nn]=nyhendetelegraf,oppsett,innstillingar +Keywords[pl]=news ticker,wiadomości,nagłówki,konfiguracja,ustawienia +Keywords[pt]=notícias, configurar, configuração +Keywords[pt_BR]=mostrador de notícias,configurar, preferências +Keywords[ru]=news ticker, configure, settings, настройка, новости +Keywords[sk]=zdroje správ,nastavenie +Keywords[sl]=prikazovalnik novic, nastavi, nastavitve +Keywords[sr]=news ticker, подеси, поставке +Keywords[sr@Latn]=news ticker, podesi, postavke +Keywords[sv]=nyhetsövervakare, anpassa, inställningar +Keywords[ta]=கேமுகவரிப்புத்தகம்,கட்டமைப்பு,அமைவுகள் +Keywords[tg]=news ticker, configure, settings, танзимот +Keywords[tr]=haber izleyici, yapılandırma, yapılandır +Keywords[uk]=новини, налаштування, параметри +Keywords[zh_CN]=news ticker, configure, settings, 新闻点点通, 配置, 设置 diff --git a/kontact/plugins/newsticker/kcmkontactknt.h b/kontact/plugins/newsticker/kcmkontactknt.h new file mode 100644 index 000000000..7463cf004 --- /dev/null +++ b/kontact/plugins/newsticker/kcmkontactknt.h @@ -0,0 +1,102 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KCMKONTACTKNT_H +#define KCMKONTACTKNT_H + +#include <kcmodule.h> + +class QListViewItem; +class QSpinxBox; + +class KAboutData; +class KListView; +class KPushButton; + +class NewsItem; + +class KCMKontactKNT : public KCModule +{ + Q_OBJECT + + public: + KCMKontactKNT( QWidget *parent = 0, const char *name = 0 ); + + virtual void load(); + virtual void save(); + virtual void defaults(); + virtual const KAboutData* aboutData() const; + + private slots: + void addNews(); + void removeNews(); + void newFeed(); + void deleteFeed(); + + void selectedChanged( QListViewItem *item ); + void allCurrentChanged( QListViewItem *item ); + + void modified(); + + private: + void initGUI(); + void loadNews(); + void loadCustomNews(); + void storeCustomNews(); + void scanNews(); + + bool dcopActive() const; + + KListView *mAllNews; + KListView *mSelectedNews; + QListViewItem *mCustomItem; + + KPushButton *mAddButton; + KPushButton *mRemoveButton; + KPushButton *mNewButton; + KPushButton *mDeleteButton; + QSpinBox *mUpdateInterval; + QSpinBox *mArticleCount; + + QMap<QString, QString> mFeedMap; + QValueList<NewsItem*> mCustomFeeds; +}; + +class NewsEditDialog : public KDialogBase +{ + Q_OBJECT + + public: + NewsEditDialog( const QString&, const QString&, QWidget *parent ); + QString title() const; + QString url() const; + + private slots: + void modified(); + + private: + QLineEdit *mTitle; + QLineEdit *mURL; +}; + +#endif diff --git a/kontact/plugins/newsticker/newsfeeds.h b/kontact/plugins/newsticker/newsfeeds.h new file mode 100644 index 000000000..fb5ef4098 --- /dev/null +++ b/kontact/plugins/newsticker/newsfeeds.h @@ -0,0 +1,315 @@ +/* + This file is part of Kontact. + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef NEWSFEEDS_H +#define NEWSFEEDS_H + +#include <qvaluelist.h> + +#define DEFAULT_NEWSSOURCES 60 + +class NewsSourceData +{ + public: + typedef QValueList<NewsSourceData> List; + + enum Category { Arts, Business, Computers, Misc, + Recreation, Society }; + + NewsSourceData( const QString &name = I18N_NOOP( "Unknown" ), + const QString &url = QString::null, + const QString &icon = QString::null, + const Category category= Computers ) + : mName( name ), mURL( url ), mIcon( icon ), mCategory( category ) + { + } + + QString name() const { return mName; } + QString url() const { return mURL; } + QString icon() const { return mIcon; } + Category category() const { return mCategory; } + + QString mName; + QString mURL; + QString mIcon; + Category mCategory; +}; + +static NewsSourceData NewsSourceDefault[DEFAULT_NEWSSOURCES] = { + // Arts --------------- + NewsSourceData( + QString::fromLatin1("Bureau 42"), + QString::fromLatin1("http://www.bureau42.com/rdf/"), + QString::fromLatin1("http://www.bureau42.com/favicon.ico"), + NewsSourceData::Arts ), + NewsSourceData( + QString::fromLatin1("eFilmCritic"), + QString::fromLatin1("http://efilmcritic.com/fo.rdf"), + QString::fromLatin1("http://efilmcritic.com/favicon.ico"), + NewsSourceData::Arts ), + // Business ----------- + NewsSourceData( + QString::fromLatin1("Internet.com Business"), + QString::fromLatin1("http://headlines.internet.com/internetnews/bus-news/news.rss"), + QString::null, + NewsSourceData::Business ), + NewsSourceData( + QString::fromLatin1("TradeSims"), + QString::fromLatin1("http://www.tradesims.com/AEX.rdf"), + QString::null, + NewsSourceData::Business ), + // Computers ---------- + NewsSourceData( + QString::fromLatin1("KDE Deutschland"), + QString::fromLatin1("http://www.kde.de/nachrichten/nachrichten.rdf"), + QString::fromLatin1("http://www.kde.de/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("KDE France"), + QString::fromLatin1("http://www.kde-france.org/backend-breves.php3"), + QString::null, + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("FreeBSD Project News"), + QString::fromLatin1("http://www.freebsd.org/news/news.rdf"), + QString::fromLatin1("http://www.freebsd.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("dot.kde.org"), + QString::fromLatin1("http://www.kde.org/dotkdeorg.rdf"), + QString::fromLatin1("http://www.kde.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( QString::fromLatin1("KDE-Look.org"), + QString::fromLatin1("http://www.kde.org/kde-look-content.rdf"), + QString::fromLatin1("http://kde-look.org/img/favicon-1-1.ico"), + NewsSourceData::Computers ), + NewsSourceData( QString::fromLatin1("KDE-Apps.org"), + QString::fromLatin1("http://www.kde.org/dot/kde-apps-content.rdf"), + QString::fromLatin1("http://kde-apps.org/img/favicon-1-1.ico"), + NewsSourceData::Computers ), + NewsSourceData( QString::fromLatin1("DesktopLinux"), + QString::fromLatin1("http://www.desktoplinux.com/backend/index.html"), + QString::fromLatin1("http://www.desktoplinux.com/images/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( QString::fromLatin1("DistroWatch"), + QString::fromLatin1("http://distrowatch.com/news/dw.xml"), + QString::fromLatin1("http://distrowatch.com/favicon.ico"), + NewsSourceData::Computers ), + /*URL changed*/ + NewsSourceData( + QString::fromLatin1("GNOME News"), + QString::fromLatin1("http://www.gnomedesktop.org/node/feed"), + QString::null, + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Slashdot"), + QString::fromLatin1("http://slashdot.org/slashdot.rdf"), + QString::fromLatin1("http://slashdot.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Ask Slashdot"), + QString::fromLatin1("http://slashdot.org/askslashdot.rdf"), + QString::fromLatin1("http://slashdot.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Slashdot: Features"), + QString::fromLatin1("http://slashdot.org/features.rdf"), + QString::fromLatin1("http://slashdot.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Slashdot: Apache"), + QString::fromLatin1("http://slashdot.org/apache.rdf"), + QString::fromLatin1("http://slashdot.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Slashdot: Books"), + QString::fromLatin1("http://slashdot.org/books.rdf"), + QString::fromLatin1("http://slashdot.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Jabber News"), + QString::fromLatin1("http://www.jabber.org/news/rss.xml"), + QString::null, + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Freshmeat"), + QString::fromLatin1("http://freshmeat.net/backend/fm.rdf"), + QString::fromLatin1("http://freshmeat.net/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Linux Weekly News"), + QString::fromLatin1("http://www.lwn.net/headlines/rss"), + QString::fromLatin1("http://www.lwn.net/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("heise online news"), + QString::fromLatin1("http://www.heise.de/newsticker/heise.rdf"), + QString::fromLatin1("http://www.heise.de/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("RUS-CERT Ticker"), + QString::fromLatin1("http://cert.uni-stuttgart.de/ticker/rus-cert.rdf"), + QString::fromLatin1("http://cert.uni-stuttgart.de/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("RUS-CERT Elsewhere"), + QString::fromLatin1("http://cert.uni-stuttgart.de/ticker/rus-cert-elsewhere.rdf"), + QString::fromLatin1("http://cert.uni-stuttgart.de/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Kuro5hin"), + QString::fromLatin1("http://kuro5hin.org/backend.rdf"), + QString::fromLatin1("http://kuro5hin.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Prolinux"), + QString::fromLatin1("http://www.pl-forum.de/backend/pro-linux.rdf"), + QString::fromLatin1("http://www.prolinux.de/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("LinuxSecurity.com"), + QString::fromLatin1("http://www.linuxsecurity.com/linuxsecurity_hybrid.rdf"), + QString::fromLatin1("http://www.linuxsecurity.com/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Linux Game Tome"), + QString::fromLatin1("http://happypenguin.org/html/news.rdf"), + QString::null, + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Mozilla"), + QString::fromLatin1("http://www.mozilla.org/news.rdf"), + QString::fromLatin1("http://www.mozillazine.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("MozillaZine"), + QString::fromLatin1("http://www.mozillazine.org/contents.rdf"), + QString::fromLatin1("http://www.mozillazine.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Daemon News"), + QString::fromLatin1("http://daily.daemonnews.org/ddn.rdf.php3"), + QString::null, + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("use Perl;"), + QString::fromLatin1("http://use.perl.org/useperl.rdf"), + QString::null, + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Root prompt"), + QString::fromLatin1("http://www.rootprompt.org/rss/"), + QString::fromLatin1("http://www.rootprompt.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("SecurityFocus"), + QString::fromLatin1("http://www.securityfocus.com/topnews-rdf.html"), + QString::fromLatin1("http://www.securityfocus.com/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("Arstechnica"), + QString::fromLatin1("http://arstechnica.com/etc/rdf/ars.rdf"), + QString::fromLatin1("http://arstechnica.com/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("amiga-news.de - deutschsprachige Amiga Nachrichten"), + QString::fromLatin1("http://www.amiga-news.de/de/backends/news/index.rss"), + QString::fromLatin1("http://www.amiga-news.de/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("amiga-news.de - english Amiga news"), + QString::fromLatin1("http://www.amiga-news.de/en/backends/news/index.rss"), + QString::fromLatin1("http://www.amiga-news.de/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("FreshPorts - the place for ports"), + QString::fromLatin1("http://www.freshports.org/news.php3"), + QString::fromLatin1("http://www.freshports.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("zez.org - about code "), + QString::fromLatin1("http://zez.org/article/rssheadlines"), + QString::null, + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("BSDatwork.com"), + QString::fromLatin1("http://BSDatwork.com/backend.php"), + QString::fromLatin1("http://BSDatwork.com/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("FreshSource - the place for source"), + QString::fromLatin1("http://www.freshsource.org/news.php"), + QString::fromLatin1("http://www.freshsource.org/favicon.ico"), + NewsSourceData::Computers ), + NewsSourceData( + QString::fromLatin1("The FreeBSD Diary"), + QString::fromLatin1("http://www.freebsddiary.org/news.php"), + QString::fromLatin1("http://www.freebsddiary.org/favicon.ico"), + NewsSourceData::Computers ), + // Miscellaneous ------ + NewsSourceData( + QString::fromLatin1("tagesschau.de"), + QString::fromLatin1("http://www.tagesschau.de/newsticker.rdf"), + QString::fromLatin1("http://www.tagesschau.de/favicon.ico"), + NewsSourceData::Misc ), + NewsSourceData( + QString::fromLatin1("CNN Top Stories"), + QString::fromLatin1("http://rss.cnn.com/rss/cnn_topstories.rss"), + QString::fromLatin1("http://www.cnn.com/favicon.ico"), + NewsSourceData::Misc ), + /*feed URL changed*/ + NewsSourceData( + QString::fromLatin1("HotWired"), + QString::fromLatin1("http://www.wired.com/news/feeds/rss2/0,2610,,00.xml"), + QString::fromLatin1("http://www.hotwired.com/favicon.ico"), + NewsSourceData::Misc ), + NewsSourceData( + QString::fromLatin1("The Register"), + QString::fromLatin1("http://www.theregister.co.uk/headlines.rss"), + QString::fromLatin1("http://www.theregister.co.uk/favicon.ico"), + NewsSourceData::Misc ), + NewsSourceData( + QString::fromLatin1( "Christian Science Monitor" ), + QString::fromLatin1( "http://www.csmonitor.com/rss/csm.rss"), + QString::fromLatin1( "http://www.csmonitor.com/favicon.ico"), + NewsSourceData::Misc ), + // Recreation + // Society + NewsSourceData( + QString::fromLatin1("nippon.it"), + QString::fromLatin1("http://www.nippon.it/backend.it.php"), + QString::fromLatin1("http://www.nippon.it/favicon.ico"), + NewsSourceData::Society ), + NewsSourceData( + QString::fromLatin1( "gflash" ), + QString::fromLatin1( "http://www.gflash.de/backend.php"), + QString::fromLatin1( "http://www.gflash.de/favicon.ico"), + NewsSourceData::Society ), + NewsSourceData( + QString::fromLatin1( "Quintessenz" ), + QString::fromLatin1( "http://quintessenz.at/cgi-bin/rdf"), + QString::fromLatin1( "http://quintessenz.at/favicon.ico"), + NewsSourceData::Society ) +}; + +#endif diff --git a/kontact/plugins/newsticker/newsticker_plugin.cpp b/kontact/plugins/newsticker/newsticker_plugin.cpp new file mode 100644 index 000000000..0bc42bd14 --- /dev/null +++ b/kontact/plugins/newsticker/newsticker_plugin.cpp @@ -0,0 +1,43 @@ +/* + This file is part of Kontact. + Copyright (C) 2003 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <kgenericfactory.h> +#include <klocale.h> +#include <kparts/componentfactory.h> +#include "core.h" + +#include "summarywidget.h" + +#include "newsticker_plugin.h" + +typedef KGenericFactory< NewsTickerPlugin, Kontact::Core > NewsTickerPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_newstickerplugin, + NewsTickerPluginFactory( "kontact_newstickerplugin" ) ) + +NewsTickerPlugin::NewsTickerPlugin( Kontact::Core *core, const char *name, const QStringList& ) + : Kontact::Plugin( core, core, name ) +{ + setInstance( NewsTickerPluginFactory::instance() ); +} + +Kontact::Summary *NewsTickerPlugin::createSummaryWidget( QWidget* parentWidget ) +{ + return new SummaryWidget( parentWidget ); +} diff --git a/kontact/plugins/newsticker/newsticker_plugin.h b/kontact/plugins/newsticker/newsticker_plugin.h new file mode 100644 index 000000000..d912da797 --- /dev/null +++ b/kontact/plugins/newsticker/newsticker_plugin.h @@ -0,0 +1,40 @@ +/* + This file is part of Kontact. + Copyright (C) 2003 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef NEWSTICKER_PLUGIN_H +#define NEWSTICKER_PLUGIN_H + +#include "plugin.h" + +class SummaryWidget; + +class NewsTickerPlugin : public Kontact::Plugin +{ + public: + NewsTickerPlugin( Kontact::Core *core, const char *name, const QStringList& ); + NewsTickerPlugin(); + + virtual Kontact::Summary *createSummaryWidget( QWidget* parentWidget ); + + protected: + virtual KParts::ReadOnlyPart* createPart() { return 0L; } +}; + +#endif diff --git a/kontact/plugins/newsticker/newstickerplugin.desktop b/kontact/plugins/newsticker/newstickerplugin.desktop new file mode 100644 index 000000000..18a34cda9 --- /dev/null +++ b/kontact/plugins/newsticker/newstickerplugin.desktop @@ -0,0 +1,99 @@ +[Desktop Entry] +Type=Service +Icon=knewsticker +ServiceTypes=Kontact/Plugin,KPluginInfo +TryExec=rssservice + +X-KDE-Library=libkontact_newstickerplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPluginHasSummary=true +X-KDE-KontactPluginHasPart=false + +X-KDE-PluginInfo-Name=kontact_newstickerplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Newsticker Component +Comment[bg]=Компонент за новини +Comment[ca]=Component de teletip de notícies +Comment[da]=Nyhedstelegraf-komponent +Comment[de]=Newsticker-Komponente +Comment[el]=Συστατικό προβολέα ειδήσεων +Comment[es]=Componente de teletipo de noticias +Comment[et]=Uudistejälgija plugin +Comment[fr]=Composant Newsticker +Comment[is]=Fréttastrimilseining +Comment[it]=Componente ticker notizie +Comment[ja]=ニュースティッカーコンポーネント +Comment[km]=សមាសភាគ Newsticker +Comment[nds]=Narichtentelegraaf-Komponent +Comment[nl]=Nieuwstickercomponent +Comment[pl]=Składnik paska wiadomości +Comment[ru]=Компонент новостей +Comment[sr]=Компонента откуцавача вести +Comment[sr@Latn]=Komponenta otkucavača vesti +Comment[sv]=Nyhetsövervakningskomponent +Comment[tr]=Haber İzleyici Bileşeni +Comment[zh_CN]=新闻点点通组件 +Comment[zh_TW]=新聞顯示組件 +Name=News +Name[af]=Nuus +Name[ar]=الأخبار +Name[be]=Навіны +Name[bg]=Новини +Name[br]=Keleier +Name[bs]=Usenet +Name[ca]=Notícies +Name[cs]=Novinky +Name[cy]=Newyddion +Name[da]=Nyheder +Name[de]=Usenet +Name[el]=Νέα +Name[eo]=Novaĵoj +Name[es]=Noticias +Name[et]=Uudisegrupid +Name[eu]=Berriak +Name[fa]=اخبار +Name[fi]=Uutiset +Name[fr]=Nouvelles +Name[fy]=Nijs +Name[ga]=Nuacht +Name[gl]=Novas +Name[he]=חדשות +Name[hi]=समाचार +Name[hu]=Hírek +Name[is]=Fréttir +Name[ja]=ニュース +Name[ka]=სიახლეები +Name[kk]=Жаңалықтар +Name[km]=ព័ត៌មាន +Name[lt]=Naujienos +Name[mk]=Вести +Name[ms]=Berita +Name[nb]=Njus +Name[nds]=Narichten +Name[ne]=समाचार +Name[nl]=Nieuws +Name[nn]=Nyheiter +Name[pa]=ਖ਼ਬਰਾਂ +Name[pl]=Listy dyskusyjne +Name[pt]=Notícias +Name[pt_BR]=Notícias +Name[ro]=Ştiri +Name[ru]=Новости +Name[se]=Ođđasat +Name[sk]=Diskusné skupiny +Name[sl]=Novice +Name[sr]=Вести +Name[sr@Latn]=Vesti +Name[sv]=Nyheter +Name[ta]=செய்திகள் +Name[tg]=Ахборот +Name[th]=ข่าว +Name[tr]=Haberler +Name[uk]=Новини +Name[uz]=Yangiliklar +Name[uz@cyrillic]=Янгиликлар +Name[zh_CN]=新闻 +Name[zh_TW]=新聞 diff --git a/kontact/plugins/newsticker/summarywidget.cpp b/kontact/plugins/newsticker/summarywidget.cpp new file mode 100644 index 000000000..14b7bc27a --- /dev/null +++ b/kontact/plugins/newsticker/summarywidget.cpp @@ -0,0 +1,319 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qclipboard.h> +#include <qeventloop.h> +#include <qhbox.h> +#include <qlayout.h> +#include <qpixmap.h> +#include <qpopupmenu.h> +#include <qcursor.h> + +#include <dcopclient.h> +#include <kapplication.h> +#include <kcharsets.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kurllabel.h> + +#include "summarywidget.h" + +SummaryWidget::SummaryWidget( QWidget *parent, const char *name ) + : Kontact::Summary( parent, name ), + DCOPObject( "NewsTickerPlugin" ), mLayout( 0 ), mFeedCounter( 0 ) +{ + QVBoxLayout *vlay = new QVBoxLayout( this, 3, 3 ); + + QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_news", + KIcon::Desktop, KIcon::SizeMedium ); + + QWidget *header = createHeader( this, icon, i18n( "News Feeds" ) ); + vlay->addWidget( header ); + + QString error; + QCString appID; + + bool dcopAvailable = true; + if ( !kapp->dcopClient()->isApplicationRegistered( "rssservice" ) ) { + if ( KApplication::startServiceByDesktopName( "rssservice", QStringList(), &error, &appID ) ) { + QLabel *label = new QLabel( i18n( "No rss dcop service available.\nYou need rssservice to use this plugin." ), this ); + vlay->addWidget( label, Qt::AlignHCenter ); + dcopAvailable = false; + } + } + + mBaseWidget = new QWidget( this, "baseWidget" ); + vlay->addWidget( mBaseWidget ); + + connect( &mTimer, SIGNAL( timeout() ), this, SLOT( updateDocuments() ) ); + + readConfig(); + + connectDCOPSignal( 0, 0, "documentUpdateError(DCOPRef,int)", "documentUpdateError(DCOPRef, int)", false ); + + if ( dcopAvailable ) + initDocuments(); + + connectDCOPSignal( 0, 0, "added(QString)", "documentAdded(QString)", false ); + connectDCOPSignal( 0, 0, "removed(QString)", "documentRemoved(QString)", false ); +} + +int SummaryWidget::summaryHeight() const +{ + return ( mFeeds.count() == 0 ? 1 : mFeeds.count() ); +} + +void SummaryWidget::documentAdded( QString ) +{ + initDocuments(); +} + +void SummaryWidget::documentRemoved( QString ) +{ + initDocuments(); +} + +void SummaryWidget::configChanged() +{ + readConfig(); + + updateView(); +} + +void SummaryWidget::readConfig() +{ + KConfig config( "kcmkontactkntrc" ); + config.setGroup( "General" ); + + mUpdateInterval = config.readNumEntry( "UpdateInterval", 600 ); + mArticleCount = config.readNumEntry( "ArticleCount", 4 ); +} + +void SummaryWidget::initDocuments() +{ + mFeeds.clear(); + + DCOPRef dcopCall( "rssservice", "RSSService" ); + QStringList urls; + dcopCall.call( "list()" ).get( urls ); + + if ( urls.isEmpty() ) { // add default + urls.append( "http://www.kde.org/dotkdeorg.rdf" ); + dcopCall.send( "add(QString)", urls[ 0 ] ); + } + + QStringList::Iterator it; + for ( it = urls.begin(); it != urls.end(); ++it ) { + DCOPRef feedRef = dcopCall.call( "document(QString)", *it ); + + Feed feed; + feed.ref = feedRef; + feedRef.call( "title()" ).get( feed.title ); + feedRef.call( "link()" ).get( feed.url ); + feedRef.call( "pixmap()" ).get( feed.logo ); + mFeeds.append( feed ); + + disconnectDCOPSignal( "rssservice", feedRef.obj(), "documentUpdated(DCOPRef)", 0 ); + connectDCOPSignal( "rssservice", feedRef.obj(), "documentUpdated(DCOPRef)", + "documentUpdated(DCOPRef)", false ); + + if ( qApp ) + qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput | + QEventLoop::ExcludeSocketNotifiers ); + } + + updateDocuments(); +} + +void SummaryWidget::updateDocuments() +{ + mTimer.stop(); + + FeedList::Iterator it; + for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) + (*it).ref.send( "refresh()" ); + + mTimer.start( 1000 * mUpdateInterval ); +} + +void SummaryWidget::documentUpdated( DCOPRef feedRef ) +{ + ArticleMap map; + + int numArticles = feedRef.call( "count()" ); + for ( int i = 0; i < numArticles; ++i ) { + DCOPRef artRef = feedRef.call( "article(int)", i ); + QString title, url; + + if ( qApp ) + qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput | + QEventLoop::ExcludeSocketNotifiers ); + + artRef.call( "title()" ).get( title ); + artRef.call( "link()" ).get( url ); + + QPair<QString, KURL> article(title, KURL( url )); + map.append( article ); + } + + FeedList::Iterator it; + for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) + if ( (*it).ref.obj() == feedRef.obj() ) { + (*it).map = map; + if ( (*it).title.isEmpty() ) + feedRef.call( "title()" ).get( (*it).title ); + if ( (*it).url.isEmpty() ) + feedRef.call( "link()" ).get( (*it).url ); + if ( (*it).logo.isNull() ) + feedRef.call( "pixmap()" ).get( (*it).logo ); + } + + mFeedCounter++; + if ( mFeedCounter == mFeeds.count() ) { + mFeedCounter = 0; + updateView(); + } +} + +void SummaryWidget::updateView() +{ + mLabels.setAutoDelete( true ); + mLabels.clear(); + mLabels.setAutoDelete( false ); + + delete mLayout; + mLayout = new QVBoxLayout( mBaseWidget, 3 ); + + QFont boldFont; + boldFont.setBold( true ); + boldFont.setPointSize( boldFont.pointSize() + 2 ); + + FeedList::Iterator it; + for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) { + QHBox *hbox = new QHBox( mBaseWidget ); + mLayout->addWidget( hbox ); + + // icon + KURLLabel *urlLabel = new KURLLabel( hbox ); + urlLabel->setURL( (*it).url ); + urlLabel->setPixmap( (*it).logo ); + urlLabel->setMaximumSize( urlLabel->minimumSizeHint() ); + mLabels.append( urlLabel ); + + connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + kapp, SLOT( invokeBrowser( const QString& ) ) ); + connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ), + this, SLOT( rmbMenu( const QString& ) ) ); + + // header + QLabel *label = new QLabel( hbox ); + label->setText( KCharsets::resolveEntities( (*it).title ) ); + label->setAlignment( AlignLeft|AlignVCenter ); + label->setFont( boldFont ); + label->setIndent( 6 ); + label->setMaximumSize( label->minimumSizeHint() ); + mLabels.append( label ); + + hbox->setMaximumWidth( hbox->minimumSizeHint().width() ); + hbox->show(); + + // articles + ArticleMap articles = (*it).map; + ArticleMap::Iterator artIt; + int numArticles = 0; + for ( artIt = articles.begin(); artIt != articles.end() && numArticles < mArticleCount; ++artIt ) { + urlLabel = new KURLLabel( (*artIt).second.url(), (*artIt).first, mBaseWidget ); + urlLabel->installEventFilter( this ); + //TODO: RichText causes too much horizontal space between articles + //urlLabel->setTextFormat( RichText ); + mLabels.append( urlLabel ); + mLayout->addWidget( urlLabel ); + + connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + kapp, SLOT( invokeBrowser( const QString& ) ) ); + connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ), + this, SLOT( rmbMenu( const QString& ) ) ); + + + numArticles++; + } + } + + for ( QLabel *label = mLabels.first(); label; label = mLabels.next() ) + label->show(); +} + +void SummaryWidget::documentUpdateError( DCOPRef feedRef, int errorCode ) +{ + kdDebug() << " error while updating document, error code: " << errorCode << endl; + FeedList::Iterator it; + for ( it = mFeeds.begin(); it != mFeeds.end(); ++it ) { + if ( (*it).ref.obj() == feedRef.obj() ) { + mFeeds.remove( it ); + break; + } + } + + if ( mFeedCounter == mFeeds.count() ) { + mFeedCounter = 0; + updateView(); + } + +} + +QStringList SummaryWidget::configModules() const +{ + return "kcmkontactknt.desktop"; +} + +void SummaryWidget::updateSummary( bool ) +{ + updateDocuments(); +} + +void SummaryWidget::rmbMenu( const QString& url ) +{ + QPopupMenu menu; + menu.insertItem( i18n( "Copy URL to Clipboard" ) ); + int id = menu.exec( QCursor::pos() ); + if ( id != -1 ) + kapp->clipboard()->setText( url, QClipboard::Clipboard ); +} + +bool SummaryWidget::eventFilter( QObject *obj, QEvent* e ) +{ + if ( obj->inherits( "KURLLabel" ) ) { + KURLLabel* label = static_cast<KURLLabel*>( obj ); + if ( e->type() == QEvent::Enter ) + emit message( label->url() ); + if ( e->type() == QEvent::Leave ) + emit message( QString::null ); + } + + return Kontact::Summary::eventFilter( obj, e ); +} + +#include "summarywidget.moc" diff --git a/kontact/plugins/newsticker/summarywidget.h b/kontact/plugins/newsticker/summarywidget.h new file mode 100644 index 000000000..ad914334b --- /dev/null +++ b/kontact/plugins/newsticker/summarywidget.h @@ -0,0 +1,115 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SUMMARYWIDGET_H +#define SUMMARYWIDGET_H + +#include <dcopobject.h> +#include <dcopref.h> + +#include <qmap.h> +#include <qptrlist.h> +#include <qtimer.h> +#include <qwidget.h> + +#include "summary.h" +#include <kurl.h> + +class QVBoxLayout; +class QLabel; + +class DCOPRef; +class KURLLabel; + +typedef QValueList< QPair<QString, KURL> > ArticleMap; + +typedef struct { + DCOPRef ref; + QString title; + QString url; + QPixmap logo; + ArticleMap map; +} Feed; + +typedef QValueList<Feed> FeedList; + +class SummaryWidget : public Kontact::Summary, public DCOPObject +{ + Q_OBJECT + K_DCOP + + public: + SummaryWidget( QWidget *parent, const char *name = 0 ); + + int summaryHeight() const; + QStringList configModules() const; + + k_dcop: + /** + * Inform the newsticker summary widget that an RSSDocument has been updated. + */ + void documentUpdated( DCOPRef ); + /** + * Inform the newsticker summary widget that a feed has been added. + */ + void documentAdded( QString ); + /** + * Inform the newsticker summary widget that a feed has been removed. + */ + void documentRemoved( QString ); + /** + * Inform the newsticker summary widget that an error occurred while updating a feed. + * @param ref DCOPRef to the failing RSSDocument. + * @param errorCode indicates the cause of the failure: 1 = RSS Parse Error, 2 = Could not access file, 3 = Unknown error. + */ + void documentUpdateError( DCOPRef ref, int errorCode ); + + public slots: + void updateSummary( bool force = false ); + void configChanged(); + + protected slots: + void updateDocuments(); + void rmbMenu( const QString& ); + + protected: + virtual bool eventFilter( QObject *obj, QEvent *e ); + void initDocuments(); + void updateView(); + void readConfig(); + + private: + QVBoxLayout *mLayout; + QWidget* mBaseWidget; + + QPtrList<QLabel> mLabels; + + FeedList mFeeds; + + QTimer mTimer; + int mUpdateInterval; + int mArticleCount; + uint mFeedCounter; +}; + +#endif diff --git a/kontact/plugins/specialdates/Makefile.am b/kontact/plugins/specialdates/Makefile.am new file mode 100644 index 000000000..7bedb2051 --- /dev/null +++ b/kontact/plugins/specialdates/Makefile.am @@ -0,0 +1,31 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces \ + -I$(top_srcdir)/libkdepim \ + -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_specialdatesplugin.la kcm_sdsummary.la +libkontact_specialdatesplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_specialdatesplugin_la_LIBADD = \ + $(top_builddir)/kontact/interfaces/libkpinterfaces.la \ + $(top_builddir)/libkdepim/libkdepim.la \ + $(top_builddir)/libkholidays/libkholidays.la \ + $(top_builddir)/korganizer/libkorganizer_calendar.la \ + $(top_builddir)/kaddressbook/libkaddressbook.la + +libkontact_specialdatesplugin_la_SOURCES = specialdates_plugin.cpp \ + sdsummarywidget.cpp + +kcm_sdsummary_la_SOURCES = kcmsdsummary.cpp +kcm_sdsummary_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) \ + -avoid-version -no-undefined +kcm_sdsummary_la_LIBADD = $(LIB_KDEUI) + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = specialdatesplugin.desktop + +kde_services_DATA = kcmsdsummary.desktop + +specialdatesiface_DIR = $(top_srcdir)/specialdates +kmailIface_DIR = $(top_srcdir)/kmail +kmailIface_DCOPIDLNG = true diff --git a/kontact/plugins/specialdates/kcmsdsummary.cpp b/kontact/plugins/specialdates/kcmsdsummary.cpp new file mode 100644 index 000000000..9bb0211a5 --- /dev/null +++ b/kontact/plugins/specialdates/kcmsdsummary.cpp @@ -0,0 +1,248 @@ +/* + This file is part of Kontact. + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qspinbox.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kaccelmanager.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <klocale.h> + +#include "kcmsdsummary.h" + +#include <kdepimmacros.h> + +extern "C" +{ + KDE_EXPORT KCModule *create_sdsummary( QWidget *parent, const char * ) + { + return new KCMSDSummary( parent, "kcmsdsummary" ); + } +} + +KCMSDSummary::KCMSDSummary( QWidget *parent, const char *name ) + : KCModule( parent, name ) +{ + initGUI(); + + customDaysChanged( 1 ); + + connect( mDaysGroup, SIGNAL( clicked( int ) ), SLOT( modified() ) ); + connect( mDaysGroup, SIGNAL( clicked( int ) ), SLOT( buttonClicked( int ) ) ); + connect( mCalendarGroup, SIGNAL( clicked( int ) ), SLOT( modified() ) ); + connect( mContactGroup, SIGNAL( clicked( int ) ), SLOT( modified() ) ); + connect( mCustomDays, SIGNAL( valueChanged( int ) ), SLOT( modified() ) ); + connect( mCustomDays, SIGNAL( valueChanged( int ) ), SLOT( customDaysChanged( int ) ) ); + + KAcceleratorManager::manage( this ); + + load(); +} + +void KCMSDSummary::modified() +{ + emit changed( true ); +} + +void KCMSDSummary::buttonClicked( int id ) +{ + mCustomDays->setEnabled( id == 4 ); +} + +void KCMSDSummary::customDaysChanged( int value ) +{ + mCustomDays->setSuffix( i18n( " day", " days", value ) ); +} + +void KCMSDSummary::initGUI() +{ + QGridLayout *layout = new QGridLayout( this, 3, 2, KDialog::spacingHint() ); + + mDaysGroup = new QButtonGroup( 0, Vertical, i18n( "Special Dates Summary" ), this ); + QVBoxLayout *boxLayout = new QVBoxLayout( mDaysGroup->layout(), + KDialog::spacingHint() ); + + QLabel *label = new QLabel( i18n( "How many days should the special dates summary show at once?" ), mDaysGroup ); + boxLayout->addWidget( label ); + + QRadioButton *button = new QRadioButton( i18n( "One day" ), mDaysGroup ); + boxLayout->addWidget( button ); + + button = new QRadioButton( i18n( "Five days" ), mDaysGroup ); + boxLayout->addWidget( button ); + + button = new QRadioButton( i18n( "One week" ), mDaysGroup ); + boxLayout->addWidget( button ); + + button = new QRadioButton( i18n( "One month" ), mDaysGroup ); + boxLayout->addWidget( button ); + + QHBoxLayout *hbox = new QHBoxLayout( boxLayout, KDialog::spacingHint() ); + + button = new QRadioButton( "", mDaysGroup ); + hbox->addWidget( button ); + + mCustomDays = new QSpinBox( 1, 365, 1, mDaysGroup ); + mCustomDays->setEnabled( false ); + hbox->addWidget( mCustomDays ); + + hbox->addStretch( 1 ); + + layout->addMultiCellWidget( mDaysGroup, 0, 0, 0, 1 ); + + mCalendarGroup = new QButtonGroup( 1, Horizontal, i18n( "Special Dates From Calendar" ), this ); + + mShowBirthdaysFromCal = new QCheckBox( i18n( "Show birthdays" ), mCalendarGroup ); + mShowAnniversariesFromCal = new QCheckBox( i18n( "Show anniversaries" ), mCalendarGroup ); + mShowHolidays = new QCheckBox( i18n( "Show holidays" ), mCalendarGroup ); + + mShowSpecialsFromCal = new QCheckBox( i18n( "Show special occasions" ), mCalendarGroup ); + + mContactGroup = new QButtonGroup( 1, Horizontal, i18n( "Special Dates From Contact List" ), this ); + + mShowBirthdaysFromKAB = new QCheckBox( i18n( "Show birthdays" ), mContactGroup ); + mShowAnniversariesFromKAB = new QCheckBox( i18n( "Show anniversaries" ), mContactGroup ); + + layout->addWidget( mCalendarGroup, 1, 0 ); + layout->addWidget( mContactGroup, 1, 1 ); + + layout->setRowStretch( 2, 1 ); +} + +void KCMSDSummary::load() +{ + KConfig config( "kcmsdsummaryrc" ); + + config.setGroup( "Days" ); + int days = config.readNumEntry( "DaysToShow", 7 ); + if ( days == 1 ) + mDaysGroup->setButton( 0 ); + else if ( days == 5 ) + mDaysGroup->setButton( 1 ); + else if ( days == 7 ) + mDaysGroup->setButton( 2 ); + else if ( days == 31 ) + mDaysGroup->setButton( 3 ); + else { + mDaysGroup->setButton( 4 ); + mCustomDays->setValue( days ); + mCustomDays->setEnabled( true ); + } + + config.setGroup( "EventTypes" ); + + mShowBirthdaysFromKAB-> + setChecked( config.readBoolEntry( "ShowBirthdaysFromContacts", true ) ); + mShowBirthdaysFromCal-> + setChecked( config.readBoolEntry( "ShowBirthdaysFromCalendar", true ) ); + + mShowAnniversariesFromKAB-> + setChecked( config.readBoolEntry( "ShowAnniversariesFromContacts", true ) ); + mShowAnniversariesFromCal-> + setChecked( config.readBoolEntry( "ShowAnniversariesFromCalendar", true ) ); + + mShowHolidays-> + setChecked( config.readBoolEntry( "ShowHolidays", true ) ); + + mShowSpecialsFromCal-> + setChecked( config.readBoolEntry( "ShowSpecialsFromCalendar", true ) ); + + emit changed( false ); +} + +void KCMSDSummary::save() +{ + KConfig config( "kcmsdsummaryrc" ); + + config.setGroup( "Days" ); + + int days; + switch ( mDaysGroup->selectedId() ) { + case 0: days = 1; break; + case 1: days = 5; break; + case 2: days = 7; break; + case 3: days = 31; break; + case 4: + default: days = mCustomDays->value(); break; + } + config.writeEntry( "DaysToShow", days ); + + config.setGroup( "EventTypes" ); + + config.writeEntry( "ShowBirthdaysFromContacts", + mShowBirthdaysFromKAB->isChecked() ); + config.writeEntry( "ShowBirthdaysFromCalendar", + mShowBirthdaysFromCal->isChecked() ); + + config.writeEntry( "ShowAnniversariesFromContacts", + mShowAnniversariesFromKAB->isChecked() ); + config.writeEntry( "ShowAnniversariesFromCalendar", + mShowAnniversariesFromCal->isChecked() ); + + config.writeEntry( "ShowHolidays", + mShowHolidays->isChecked() ); + + config.writeEntry( "ShowSpecialsFromCalendar", + mShowSpecialsFromCal->isChecked() ); + + config.sync(); + + emit changed( false ); +} + +void KCMSDSummary::defaults() +{ + mDaysGroup->setButton( 7 ); + mShowBirthdaysFromKAB->setChecked( true ); + mShowBirthdaysFromCal->setChecked( true ); + mShowAnniversariesFromKAB->setChecked( true ); + mShowAnniversariesFromCal->setChecked( true ); + mShowHolidays->setChecked( true ); + mShowSpecialsFromCal->setChecked( true ); + + emit changed( true ); +} + +const KAboutData* KCMSDSummary::aboutData() const +{ + KAboutData *about = new KAboutData( I18N_NOOP( "kcmsdsummary" ), + I18N_NOOP( "Special Dates Configuration Dialog" ), + 0, 0, KAboutData::License_GPL, + I18N_NOOP( "(c) 2004 Tobias Koenig" ) ); + + about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" ); + about->addAuthor( "Allen Winter", 0, "winter@kde.org" ); + + return about; +} + +#include "kcmsdsummary.moc" diff --git a/kontact/plugins/specialdates/kcmsdsummary.desktop b/kontact/plugins/specialdates/kcmsdsummary.desktop new file mode 100644 index 000000000..f294c3835 --- /dev/null +++ b/kontact/plugins/specialdates/kcmsdsummary.desktop @@ -0,0 +1,126 @@ +[Desktop Entry] +Icon=cookie +Type=Service +ServiceTypes=KCModule + +X-KDE-ModuleType=Library +X-KDE-Library=sdsummary +X-KDE-FactoryName=sdsummary +X-KDE-ParentApp=kontact_specialdatesplugin +X-KDE-ParentComponents=kontact_specialdatesplugin +X-KDE-CfgDlgHierarchy=KontactSummary + +Name=Special Dates Overview +Name[bg]=Преглед на специални случаи +Name[ca]=Resum de dates especials +Name[da]=Oversigt over særlige datoer +Name[de]=Übersicht über besondere Termine +Name[el]=Επισκόπηση σημαντικών ημερομηνιών +Name[es]=Resumen de fechas especiales +Name[et]=Tähtpäevade ülevaade +Name[fr]=Aperçu des dates importantes +Name[is]=Yfirlit sérstakra daga +Name[it]=Panoramica delle date speciali +Name[ja]=特別な日の要約 +Name[km]=ទិដ្ឋភាពកាលបរិច្ឆេទពិសេស +Name[nds]=Översicht besünner Daten +Name[nl]=Overzicht van speciale data +Name[pl]=Daty specjalne +Name[pt_BR]=Resumo de Datas Especiais +Name[ru]=Сводка особых дат +Name[sr]=Преглед посебних датума +Name[sr@Latn]=Pregled posebnih datuma +Name[sv]=Översikt av speciella datum +Name[tr]=Özel Tarihlere Genel Bakış +Name[zh_CN]=特殊日期概览 +Name[zh_TW]=特殊日期概觀 +Comment=Special Dates Summary Setup +Comment[af]=Spesiale datums opsomming opstelling +Comment[bg]=Настройки на специалните случаи +Comment[ca]=Configuració del resum de les dates especials +Comment[cs]=Nastavení souhrnu speciálních datumů +Comment[da]=Opsummering af opsætning af særlige datoer +Comment[de]=Einstellung der Übersicht über besondere Termine +Comment[el]=Ρύθμιση σύνοψης σημαντικών ημερομηνιών +Comment[es]=Configuración del resumen de las fechas especiales +Comment[et]=Tähtpäevade kokkuvõtte seadistus +Comment[eu]=Data berezien laburpenen konfigurazioa +Comment[fa]=برپایی خلاصۀ تاریخهای ویژه +Comment[fi]=Erikoispäivien yhteenvedon asetukset +Comment[fr]=Configuration du résumé des dates particulières +Comment[fy]=Spesjale datums oersichts opset +Comment[gl]=Configuración do Resumo de Datas Especiais +Comment[he]=תצורת תאריכים מיוחדים +Comment[hu]=A fontos dátumok áttekintőjének beállításai +Comment[is]=Yfirlitsuppsetning sérstakra daga +Comment[it]=Impostazioni per le date speciali +Comment[ja]=特別な日の要約設定 +Comment[ka]=განსაკუთრებულ თარიღთა დაიჯესტის კონფიგურაცია +Comment[kk]=Ерекше күндер тұжырымының баптауы +Comment[km]=រៀបចំសេចក្ដីសង្ខេបថ្ងៃពិសេស +Comment[lt]=Ypatingų datų santraukos sąranka +Comment[mk]=Поставувања за прегледот на специјални датуми +Comment[ms]=Setup Ringkasan Tarikh Khusus +Comment[nb]=Sammendragsoppsett for spesielle datoer +Comment[nds]=Översicht över besünner Daag instellen +Comment[ne]=विशेष मिति सारांश सेटअप +Comment[nl]=Instellingen voor speciale data in overzicht +Comment[nn]=Oppsett av samandrag for spesielle datoar +Comment[pl]=Ustawienia podsumowania dat specjalnych +Comment[pt]=Configuração do Sumário de Datas Especiais +Comment[pt_BR]=Configuração do Resumo de Datas Especiais +Comment[ru]=Настройка особых дат +Comment[sk]=Nastavenie súhrnu špeciálnych dátumov +Comment[sl]=Nastavitve povzetka posebnih datumov +Comment[sr]=Подешавање сажетка посебних датума +Comment[sr@Latn]=Podešavanje sažetka posebnih datuma +Comment[sv]=Inställning av översikt av speciella datum +Comment[ta]=விசேஷ தேதிகள் சுருக்க அமைப்பு +Comment[th]=ต้้งค่าส่วนสรุปวันพิเศษ +Comment[tr]=Özel Tarih Özeti Yapılandırması +Comment[uk]=Налаштування підсумку особливих дат +Comment[zh_CN]=特殊日期摘要设置 +Comment[zh_TW]=特殊日期摘要設定 +Keywords=birthday, anniversary, holiday, configure, settings +Keywords[af]=birtday,anniversary, holiday, conifugre, settings, verjaarsdag, herdenking, vakansie +Keywords[bg]=рождени, рожден, дни, ден, годишнина, годишнини, обобщение, birthday, anniversary, configure, settings +Keywords[ca]=data de naixement, aniversari, vacances, configuració, arranjament +Keywords[cs]=narozeniny,výročí,nastavení,nastavit,svátek +Keywords[da]=fødselsdag, årsdag, helligdage, indstil, opsætning +Keywords[de]=Geburtstag,Jahrestag,Feiertag,einstellen,Einstellungen,Einrichten +Keywords[el]=γενέθλια, επέτειος, εορτή, ρύθμιση, ρυθμίσεις +Keywords[es]=cumpleaños, aniversario, vacaciones, configurar, preferencias +Keywords[et]=sünnipäev, tähtpäev, pidupäev, seadistamine, seadistused +Keywords[eu]=urtebetezea, urteurrena, jaia, konfiguratu, ezarpenak +Keywords[fa]=تولد، جشن سالانه، تعطیلات، پیکربندی، تنظیمات +Keywords[fi]=syntymäpäivä, juhlapäivä, loma, aseta, asetukset +Keywords[fr]=anniversaire,date de naissance,vacances,configurer,paramètres,préférences +Keywords[fy]=verjaardag,jubileum,vakantie,instellingen,configuratie,feestdag, jierdei, fakânsje, ynstellings, feestdei +Keywords[gl]=cumpreanos, aniversario, vacacións, configurar, opcións +Keywords[he]=birthday, anniversary, holiday, configure, settings, יום הולדת, הולדת, שנה, יום שנה, חג, חגים, תצורה, הגדרות +Keywords[hu]=születésnap,évforduló,szabadság,konfigurálás,beállítások +Keywords[is]=afmæli, frídagar, stillingar, stilla +Keywords[it]=compleanno, anniversario, vacanze, configura, impostazioni +Keywords[ja]=誕生日,記念日,休日,設定,設定 +Keywords[ka]=დაბადების დღე,სახელობის დღე,დასვენების დღე,კონფიგურაცია,პარამეტრები +Keywords[km]=ថ្ងៃខួបកំណើត,បុណ្យខួប,វិស្សមកាល,កំណត់រចនាសម្ព័ន្ធ,ការកំណត់ +Keywords[lt]=birthday, anniversary, holiday, configure, settings, konfigūruoti, nustatymai, gimtadieniai, išeiginės,sukaktys +Keywords[mk]=birthday, anniversary, holiday, configure, settings, роденден, годишнина, конфигурирање, конфигурација, поставувања +Keywords[ms]=tarikh lahir, ulang tahun, cuti, konfigur, seting +Keywords[nb]=fødselsdag, jubileum, ferie, sette opp, innstillinger +Keywords[nds]=Geboortsdag,Johrdag,Fierdag,instellen +Keywords[ne]=जन्मदिन, वार्षिकोत्सव, बिदा, कन्फिगर, सेटिङ +Keywords[nl]=verjaardag,jubileum,vakantie,instellingen,configuratie,feestdag +Keywords[nn]=fødselsdag,bursdag,gebursdag,jubileum,ferie,helgedag,merkedag,oppsett,innstillingar +Keywords[pl]=urodziny,rocznica,rocznice,wakacje,urlop,konfiguracja,ustawienia +Keywords[pt]=data de nascimento, aniversário, feriado, configurar, configuração +Keywords[pt_BR]=aniversário,aniversário de casamento, feriados,configurar,configurações +Keywords[ru]=birthday,anniversary,configure,settings,дни рождения,настройки,праздники,годовщины +Keywords[sl]=rojstni dan, obletnica, praznik, nastavi, nastavitve +Keywords[sr]=birthday, anniversary, holiday, configure, settings, рођендан, годишњица, подеси, поставке, подешавања +Keywords[sr@Latn]=birthday, anniversary, holiday, configure, settings, rođendan, godišnjica, podesi, postavke, podešavanja +Keywords[sv]=födelsedag,årsdag,helgdag,anpassa,inställningar +Keywords[ta]=பிறந்தநாள், ஆண்டுவிழா, விடுமுறை, வடிவமைப்பு, அமைப்புகள் +Keywords[tr]=doğumgünü, evlilik yıldönümü, tatil, yapılandır, ypılandırma +Keywords[uk]=birthday, anniversary, holiday, configure, settings, день народження, ювілей, свято, налаштування, параметри +Keywords[zh_CN]=birthday, anniversary, holiday, configure, settings, 周年纪念, 配置, 设置, 假日 diff --git a/kontact/plugins/specialdates/kcmsdsummary.h b/kontact/plugins/specialdates/kcmsdsummary.h new file mode 100644 index 000000000..60b2ea082 --- /dev/null +++ b/kontact/plugins/specialdates/kcmsdsummary.h @@ -0,0 +1,69 @@ +/* + This file is part of Kontact. + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KCMSDSUMMARY_H +#define KCMSDSUMMARY_H + +#include <kcmodule.h> + +class QButtonGroup; +class QCheckBox; +class QSpinBox; + +class KAboutData; + +class KCMSDSummary : public KCModule +{ + Q_OBJECT + + public: + KCMSDSummary( QWidget *parent = 0, const char *name = 0 ); + + virtual void load(); + virtual void save(); + virtual void defaults(); + virtual const KAboutData* aboutData() const; + + private slots: + void modified(); + void buttonClicked( int ); + void customDaysChanged( int ); + + private: + void initGUI(); + + QButtonGroup *mDaysGroup; + QButtonGroup *mCalendarGroup; + QButtonGroup *mContactGroup; + QCheckBox *mShowBirthdaysFromKAB; + QCheckBox *mShowBirthdaysFromCal; + QCheckBox *mShowAnniversariesFromKAB; + QCheckBox *mShowAnniversariesFromCal; + QCheckBox *mShowHolidays; + QCheckBox *mShowHolidaysFromCal; + QCheckBox *mShowSpecialsFromCal; + QSpinBox *mCustomDays; +}; + +#endif diff --git a/kontact/plugins/specialdates/sdsummarywidget.cpp b/kontact/plugins/specialdates/sdsummarywidget.cpp new file mode 100644 index 000000000..721073490 --- /dev/null +++ b/kontact/plugins/specialdates/sdsummarywidget.cpp @@ -0,0 +1,637 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qcursor.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qimage.h> +#include <qtooltip.h> + +#include <dcopclient.h> +#include <dcopref.h> +#include <kabc/stdaddressbook.h> +#include <korganizer/stdcalendar.h> +#include <kapplication.h> +#include <kdialog.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kparts/part.h> +#include <kpopupmenu.h> +#include <kstandarddirs.h> +#include <kurllabel.h> +#include <libkcal/event.h> +#include <libkcal/resourcecalendar.h> +#include <libkcal/resourcelocal.h> +#include <libkdepim/kpimprefs.h> + +#include "core.h" +#include "plugin.h" + +#include "sdsummarywidget.h" + +enum SDIncidenceType { + IncidenceTypeContact, IncidenceTypeEvent +}; +enum SDCategory { + CategoryBirthday, CategoryAnniversary, CategoryHoliday, CategoryOther +}; + +class SDEntry +{ + public: + SDIncidenceType type; + SDCategory category; + int yearsOld; + int daysTo; + QDate date; + QString summary; + QString desc; + int span; // #days in the special occassion. + KABC::Addressee addressee; + + bool operator<( const SDEntry &entry ) const + { + return daysTo < entry.daysTo; + } +}; + +SDSummaryWidget::SDSummaryWidget( Kontact::Plugin *plugin, QWidget *parent, + const char *name ) + : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 ), mHolidays( 0 ) +{ + // Create the Summary Layout + QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 ); + + QPixmap icon = KGlobal::iconLoader()->loadIcon( "cookie", + KIcon::Desktop, KIcon::SizeMedium ); + + QWidget *header = createHeader( this, icon, i18n( "Special Dates" ) ); + mainLayout->addWidget(header); + + mLayout = new QGridLayout( mainLayout, 7, 6, 3 ); + mLayout->setRowStretch( 6, 1 ); + + // Setup the Addressbook + KABC::StdAddressBook *ab = KABC::StdAddressBook::self( true ); + connect( ab, SIGNAL( addressBookChanged( AddressBook* ) ), + this, SLOT( updateView() ) ); + connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ), + this, SLOT( updateView() ) ); + + // Setup the Calendar + mCalendar = new KCal::CalendarResources( KPimPrefs::timezone() ); + mCalendar->readConfig(); + + KCal::CalendarResourceManager *manager = mCalendar->resourceManager(); + if ( manager->isEmpty() ) { + KConfig config( "korganizerrc" ); + config.setGroup( "General" ); + QString fileName = config.readPathEntry( "Active Calendar" ); + + QString resourceName; + if ( fileName.isEmpty() ) { + fileName = locateLocal( "data", "korganizer/std.ics" ); + resourceName = i18n( "Default KOrganizer resource" ); + } else { + resourceName = i18n( "Active Calendar" ); + } + + KCal::ResourceCalendar *defaultResource = + new KCal::ResourceLocal( fileName ); + + defaultResource->setResourceName( resourceName ); + + manager->add( defaultResource ); + manager->setStandardResource( defaultResource ); + } + mCalendar = KOrg::StdCalendar::self(); + mCalendar->load(); + + connect( mCalendar, SIGNAL( calendarChanged() ), + this, SLOT( updateView() ) ); + connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ), + this, SLOT( updateView() ) ); + + // Update Configuration + configUpdated(); +} + +void SDSummaryWidget::configUpdated() +{ + KConfig config( "kcmsdsummaryrc" ); + + config.setGroup( "Days" ); + mDaysAhead = config.readNumEntry( "DaysToShow", 7 ); + + config.setGroup( "EventTypes" ); + mShowBirthdaysFromKAB = + config.readBoolEntry( "ShowBirthdaysFromContacts", true ); + mShowBirthdaysFromCal = + config.readBoolEntry( "ShowBirthdaysFromCalendar", true ); + + mShowAnniversariesFromKAB = + config.readBoolEntry( "ShowAnniversariesFromContacts", true ); + mShowAnniversariesFromCal = + config.readBoolEntry( "ShowAnniversariesFromCalendar", true ); + + mShowHolidays = + config.readBoolEntry( "ShowHolidays", true ); + + mShowSpecialsFromCal = + config.readBoolEntry( "ShowSpecialsFromCalendar", true ); + + updateView(); +} + +bool SDSummaryWidget::initHolidays() +{ + KConfig hconfig( "korganizerrc" ); + hconfig.setGroup( "Time & Date" ); + QString location = hconfig.readEntry( "Holidays" ); + if ( !location.isEmpty() ) { + if ( mHolidays ) delete mHolidays; + mHolidays = new KHolidays( location ); + return true; + } + return false; +} + +// number of days remaining in an Event +int SDSummaryWidget::span( KCal::Event *event ) +{ + int span=1; + if ( event->isMultiDay() && event->doesFloat() ) { + QDate d = event->dtStart().date(); + if ( d < QDate::currentDate() ) { + d = QDate::currentDate(); + } + while ( d < event->dtEnd().date() ) { + span++; + d=d.addDays( 1 ); + } + } + return span; +} + +// day of a multiday Event +int SDSummaryWidget::dayof( KCal::Event *event, const QDate& date ) +{ + int dayof=1; + QDate d = event->dtStart().date(); + if ( d < QDate::currentDate() ) { + d = QDate::currentDate(); + } + while ( d < event->dtEnd().date() ) { + if ( d < date ) { + dayof++; + } + d = d.addDays( 1 ); + } + return dayof; +} + + + +void SDSummaryWidget::updateView() +{ + mLabels.setAutoDelete( true ); + mLabels.clear(); + mLabels.setAutoDelete( false ); + + KABC::StdAddressBook *ab = KABC::StdAddressBook::self( true ); + QValueList<SDEntry> dates; + QLabel *label = 0; + + // No reason to show the date year + QString savefmt = KGlobal::locale()->dateFormat(); + KGlobal::locale()->setDateFormat( KGlobal::locale()-> + dateFormat().replace( 'Y', ' ' ) ); + + // Search for Birthdays and Anniversaries in the Addressbook + KABC::AddressBook::Iterator it; + for ( it = ab->begin(); it != ab->end(); ++it ) { + QDate birthday = (*it).birthday().date(); + if ( birthday.isValid() && mShowBirthdaysFromKAB ) { + SDEntry entry; + entry.type = IncidenceTypeContact; + entry.category = CategoryBirthday; + dateDiff( birthday, entry.daysTo, entry.yearsOld ); + + entry.date = birthday; + entry.addressee = *it; + entry.span = 1; + if ( entry.daysTo <= mDaysAhead ) + dates.append( entry ); + } + + QString anniversaryAsString = + (*it).custom( "KADDRESSBOOK" , "X-Anniversary" ); + if ( !anniversaryAsString.isEmpty() ) { + QDate anniversary = QDate::fromString( anniversaryAsString, Qt::ISODate ); + if ( anniversary.isValid() && mShowAnniversariesFromKAB ) { + SDEntry entry; + entry.type = IncidenceTypeContact; + entry.category = CategoryAnniversary; + dateDiff( anniversary, entry.daysTo, entry.yearsOld ); + + entry.date = anniversary; + entry.addressee = *it; + entry.span = 1; + if ( entry.daysTo <= mDaysAhead ) + dates.append( entry ); + } + } + } + + // Search for Birthdays, Anniversaries, Holidays, and Special Occasions + // in the Calendar + QDate dt; + QDate currentDate = QDate::currentDate(); + for ( dt=currentDate; + dt<=currentDate.addDays( mDaysAhead - 1 ); + dt=dt.addDays(1) ) { + KCal::Event::List events = mCalendar->events( dt, + KCal::EventSortStartDate, + KCal::SortDirectionAscending ); + KCal::Event *ev; + KCal::Event::List::ConstIterator it; + for ( it=events.begin(); it!=events.end(); ++it ) { + ev = *it; + if ( !ev->categoriesStr().isEmpty() ) { + QStringList::ConstIterator it2; + QStringList c = ev->categories(); + for ( it2=c.begin(); it2!=c.end(); ++it2 ) { + + // Append Birthday Event? + if ( mShowBirthdaysFromCal && + ( ( *it2 ).upper() == i18n( "BIRTHDAY" ) ) ) { + SDEntry entry; + entry.type = IncidenceTypeEvent; + entry.category = CategoryBirthday; + entry.date = dt; + entry.summary = ev->summary(); + entry.desc = ev->description(); + dateDiff( ev->dtStart().date(), entry.daysTo, entry.yearsOld ); + entry.span = 1; + dates.append( entry ); + break; + } + + // Append Anniversary Event? + if ( mShowAnniversariesFromCal && + ( ( *it2 ).upper() == i18n( "ANNIVERSARY" ) ) ) { + SDEntry entry; + entry.type = IncidenceTypeEvent; + entry.category = CategoryAnniversary; + entry.date = dt; + entry.summary = ev->summary(); + entry.desc = ev->description(); + dateDiff( ev->dtStart().date(), entry.daysTo, entry.yearsOld ); + entry.span = 1; + dates.append( entry ); + break; + } + + // Append Holiday Event? + if ( mShowHolidays && + ( ( *it2 ).upper() == i18n( "HOLIDAY" ) ) ) { + SDEntry entry; + entry.type = IncidenceTypeEvent; + entry.category = CategoryHoliday; + entry.date = dt; + entry.summary = ev->summary(); + entry.desc = ev->description(); + dateDiff( dt, entry.daysTo, entry.yearsOld ); + entry.yearsOld = -1; //ignore age of holidays + entry.span = span( ev ); + if ( entry.span > 1 && dayof( ev, dt ) > 1 ) // skip days 2,3,... + break; + dates.append( entry ); + break; + } + + // Append Special Occasion Event? + if ( mShowSpecialsFromCal && + ( ( *it2 ).upper() == i18n( "SPECIAL OCCASION" ) ) ) { + SDEntry entry; + entry.type = IncidenceTypeEvent; + entry.category = CategoryOther; + entry.date = dt; + entry.summary = ev->summary(); + entry.desc = ev->description(); + dateDiff( dt, entry.daysTo, entry.yearsOld ); + entry.yearsOld = -1; //ignore age of special occasions + entry.span = span( ev ); + if ( entry.span > 1 && dayof( ev, dt ) > 1 ) // skip days 2,3,... + break; + dates.append( entry ); + break; + } + } + } + } + } + + // Seach for Holidays + if ( mShowHolidays ) { + if ( initHolidays() ) { + for ( dt=currentDate; + dt<=currentDate.addDays( mDaysAhead - 1 ); + dt=dt.addDays(1) ) { + QValueList<KHoliday> holidays = mHolidays->getHolidays( dt ); + QValueList<KHoliday>::ConstIterator it = holidays.begin(); + for ( ; it != holidays.end(); ++it ) { + SDEntry entry; + entry.type = IncidenceTypeEvent; + entry.category = ((*it).Category==KHolidays::HOLIDAY)?CategoryHoliday:CategoryOther; + entry.date = dt; + entry.summary = (*it).text; + dateDiff( dt, entry.daysTo, entry.yearsOld ); + entry.yearsOld = -1; //ignore age of holidays + entry.span = 1; + dates.append( entry ); + } + } + } + } + + // Sort, then Print the Special Dates + qHeapSort( dates ); + + if ( !dates.isEmpty() ) { + int counter = 0; + QValueList<SDEntry>::Iterator addrIt; + QString lines; + for ( addrIt = dates.begin(); addrIt != dates.end(); ++addrIt ) { + bool makeBold = (*addrIt).daysTo == 0; // i.e., today + + // Pixmap + QImage icon_img; + QString icon_name; + KABC::Picture pic; + switch( (*addrIt).category ) { // TODO: better icons + case CategoryBirthday: + icon_name = "cookie"; + pic = (*addrIt).addressee.photo(); + if ( pic.isIntern() && !pic.data().isNull() ) { + QImage img = pic.data(); + if ( img.width() > img.height() ) { + icon_img = img.scaleWidth( 32 ); + } else { + icon_img = img.scaleHeight( 32 ); + } + } + break; + case CategoryAnniversary: + icon_name = "kdmconfig"; + pic = (*addrIt).addressee.photo(); + if ( pic.isIntern() && !pic.data().isNull() ) { + QImage img = pic.data(); + if ( img.width() > img.height() ) { + icon_img = img.scaleWidth( 32 ); + } else { + icon_img = img.scaleHeight( 32 ); + } + } + break; + case CategoryHoliday: + icon_name = "kdmconfig"; break; + case CategoryOther: + icon_name = "cookie"; break; + } + label = new QLabel( this ); + if ( icon_img.isNull() ) { + label->setPixmap( KGlobal::iconLoader()->loadIcon( icon_name, + KIcon::Small ) ); + } else { + label->setPixmap( icon_img ); + } + label->setMaximumWidth( label->minimumSizeHint().width() ); + label->setAlignment( AlignVCenter ); + mLayout->addWidget( label, counter, 0 ); + mLabels.append( label ); + + // Event date + QString datestr; + + //Muck with the year -- change to the year 'daysTo' days away + int year = currentDate.addDays( (*addrIt).daysTo ).year(); + QDate sD = QDate::QDate( year, + (*addrIt).date.month(), (*addrIt).date.day() ); + + if ( (*addrIt).daysTo == 0 ) { + datestr = i18n( "Today" ); + } else if ( (*addrIt).daysTo == 1 ) { + datestr = i18n( "Tomorrow" ); + } else { + datestr = KGlobal::locale()->formatDate( sD ); + } + // Print the date span for multiday, floating events, for the + // first day of the event only. + if ( (*addrIt).span > 1 ) { + QString endstr = + KGlobal::locale()->formatDate( sD.addDays( (*addrIt).span - 1 ) ); + datestr += " -\n " + endstr; + } + + label = new QLabel( datestr, this ); + label->setAlignment( AlignLeft | AlignVCenter ); + mLayout->addWidget( label, counter, 1 ); + mLabels.append( label ); + if ( makeBold ) { + QFont font = label->font(); + font.setBold( true ); + label->setFont( font ); + } + + // Countdown + label = new QLabel( this ); + if ( (*addrIt).daysTo == 0 ) { + label->setText( i18n( "now" ) ); + } else { + label->setText( i18n( "in 1 day", "in %n days", (*addrIt).daysTo ) ); + } + + label->setAlignment( AlignLeft | AlignVCenter ); + mLayout->addWidget( label, counter, 2 ); + mLabels.append( label ); + + // What + QString what; + switch( (*addrIt).category ) { + case CategoryBirthday: + what = i18n( "Birthday" ); break; + case CategoryAnniversary: + what = i18n( "Anniversary" ); break; + case CategoryHoliday: + what = i18n( "Holiday" ); break; + case CategoryOther: + what = i18n( "Special Occasion" ); break; + } + label = new QLabel( this ); + label->setText( what ); + label->setAlignment( AlignLeft | AlignVCenter ); + mLayout->addWidget( label, counter, 3 ); + mLabels.append( label ); + + // Description + if ( (*addrIt).type == IncidenceTypeContact ) { + KURLLabel *urlLabel = new KURLLabel( this ); + urlLabel->installEventFilter( this ); + urlLabel->setURL( (*addrIt).addressee.uid() ); + urlLabel->setText( (*addrIt).addressee.realName() ); + urlLabel->setTextFormat( Qt::RichText ); + mLayout->addWidget( urlLabel, counter, 4 ); + mLabels.append( urlLabel ); + + connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + this, SLOT( mailContact( const QString& ) ) ); + connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ), + this, SLOT( popupMenu( const QString& ) ) ); + } else { + label = new QLabel( this ); + label->setText( (*addrIt).summary ); + label->setTextFormat( Qt::RichText ); + mLayout->addWidget( label, counter, 4 ); + mLabels.append( label ); + if ( !(*addrIt).desc.isEmpty() ) { + QToolTip::add( label, (*addrIt).desc ); + } + } + + // Age + if ( (*addrIt).category == CategoryBirthday || + (*addrIt).category == CategoryAnniversary ) { + label = new QLabel( this ); + if ( (*addrIt).yearsOld <= 0 ) { + label->setText( "" ); + } else { + label->setText( i18n( "one year", "%n years", (*addrIt).yearsOld ) ); + } + label->setAlignment( AlignLeft | AlignVCenter ); + mLayout->addWidget( label, counter, 5 ); + mLabels.append( label ); + } + + counter++; + } + } else { + label = new QLabel( + i18n( "No special dates within the next 1 day", + "No special dates pending within the next %n days", + mDaysAhead ), this, "nothing to see" ); + label->setAlignment( AlignHCenter | AlignVCenter ); + mLayout->addMultiCellWidget( label, 0, 0, 0, 4 ); + mLabels.append( label ); + } + + for ( label = mLabels.first(); label; label = mLabels.next() ) + label->show(); + + KGlobal::locale()->setDateFormat( savefmt ); +} + +void SDSummaryWidget::mailContact( const QString &uid ) +{ + KABC::StdAddressBook *ab = KABC::StdAddressBook::self( true ); + QString email = ab->findByUid( uid ).fullEmail(); + + kapp->invokeMailer( email, QString::null ); +} + +void SDSummaryWidget::viewContact( const QString &uid ) +{ + if ( !mPlugin->isRunningStandalone() ) + mPlugin->core()->selectPlugin( "kontact_kaddressbookplugin" ); + else + mPlugin->bringToForeground(); + + DCOPRef dcopCall( "kaddressbook", "KAddressBookIface" ); + dcopCall.send( "showContactEditor(QString)", uid ); +} + +void SDSummaryWidget::popupMenu( const QString &uid ) +{ + KPopupMenu popup( this ); + popup.insertItem( KGlobal::iconLoader()->loadIcon( "kmail", KIcon::Small ), + i18n( "Send &Mail" ), 0 ); + popup.insertItem( KGlobal::iconLoader()->loadIcon( "kaddressbook", KIcon::Small ), + i18n( "View &Contact" ), 1 ); + + switch ( popup.exec( QCursor::pos() ) ) { + case 0: + mailContact( uid ); + break; + case 1: + viewContact( uid ); + break; + } +} + +bool SDSummaryWidget::eventFilter( QObject *obj, QEvent* e ) +{ + if ( obj->inherits( "KURLLabel" ) ) { + KURLLabel* label = static_cast<KURLLabel*>( obj ); + if ( e->type() == QEvent::Enter ) + emit message( i18n( "Mail to:\"%1\"" ).arg( label->text() ) ); + if ( e->type() == QEvent::Leave ) + emit message( QString::null ); + } + + return Kontact::Summary::eventFilter( obj, e ); +} + +void SDSummaryWidget::dateDiff( const QDate &date, int &days, int &years ) +{ + QDate currentDate; + QDate eventDate; + + if ( QDate::leapYear( date.year() ) && date.month() == 2 && date.day() == 29 ) { + currentDate = QDate( date.year(), QDate::currentDate().month(), QDate::currentDate().day() ); + if ( !QDate::leapYear( QDate::currentDate().year() ) ) + eventDate = QDate( date.year(), date.month(), 28 ); // celebrate one day earlier ;) + else + eventDate = QDate( date.year(), date.month(), date.day() ); + } else { + currentDate = QDate( 0, QDate::currentDate().month(), QDate::currentDate().day() ); + eventDate = QDate( 0, date.month(), date.day() ); + } + + int offset = currentDate.daysTo( eventDate ); + if ( offset < 0 ) { + days = 365 + offset; + years = QDate::currentDate().year() + 1 - date.year(); + } else { + days = offset; + years = QDate::currentDate().year() - date.year(); + } +} + +QStringList SDSummaryWidget::configModules() const +{ + return QStringList( "kcmsdsummary.desktop" ); +} + +#include "sdsummarywidget.moc" diff --git a/kontact/plugins/specialdates/sdsummarywidget.h b/kontact/plugins/specialdates/sdsummarywidget.h new file mode 100644 index 000000000..74cd08942 --- /dev/null +++ b/kontact/plugins/specialdates/sdsummarywidget.h @@ -0,0 +1,84 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SDSUMMARYWIDGET_H +#define SDSUMMARYWIDGET_H + +#include <qptrlist.h> +#include <qwidget.h> + +#include <libkcal/calendarresources.h> +#include <libkholidays/kholidays.h> + +#include "summary.h" + +namespace Kontact { + class Plugin; +} + +class QGridLayout; +class QLabel; + +class SDSummaryWidget : public Kontact::Summary +{ + Q_OBJECT + + public: + SDSummaryWidget( Kontact::Plugin *plugin, QWidget *parent, + const char *name = 0 ); + + QStringList configModules() const; + void configUpdated(); + void updateSummary( bool force = false ) { Q_UNUSED( force ); updateView(); } + + protected: + virtual bool eventFilter( QObject *obj, QEvent* e ); + + private slots: + void updateView(); + void popupMenu( const QString &uid ); + void mailContact( const QString &uid ); + void viewContact( const QString &uid ); + + private: + int span( KCal::Event *event ); + int dayof( KCal::Event *event, const QDate &date ); + bool initHolidays(); + void dateDiff( const QDate &date, int &days, int &years ); + QGridLayout *mLayout; + QPtrList<QLabel> mLabels; + Kontact::Plugin *mPlugin; + KCal::CalendarResources *mCalendar; + int mDaysAhead; + bool mShowBirthdaysFromKAB; + bool mShowBirthdaysFromCal; + bool mShowAnniversariesFromKAB; + bool mShowAnniversariesFromCal; + bool mShowHolidays; + bool mShowSpecialsFromCal; + + KHolidays::KHolidays *mHolidays; +}; + +#endif diff --git a/kontact/plugins/specialdates/specialdates_plugin.cpp b/kontact/plugins/specialdates/specialdates_plugin.cpp new file mode 100644 index 000000000..f0149fd9a --- /dev/null +++ b/kontact/plugins/specialdates/specialdates_plugin.cpp @@ -0,0 +1,70 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004-2005 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <kaboutdata.h> +#include <kgenericfactory.h> +#include <klocale.h> +#include <kparts/componentfactory.h> + +#include "core.h" +#include "sdsummarywidget.h" + +#include "specialdates_plugin.h" + +typedef KGenericFactory< SpecialdatesPlugin, Kontact::Core > SpecialdatesPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_specialdatesplugin, + SpecialdatesPluginFactory( "kontact_specialdatesplugin" ) ) + +SpecialdatesPlugin::SpecialdatesPlugin( Kontact::Core *core, const char *name, const QStringList& ) + : Kontact::Plugin( core, core, name ), + mAboutData( 0 ) +{ + setInstance( SpecialdatesPluginFactory::instance() ); +} + +SpecialdatesPlugin::~SpecialdatesPlugin() +{ +} + +Kontact::Summary *SpecialdatesPlugin::createSummaryWidget( QWidget *parentWidget ) +{ + return new SDSummaryWidget( this, parentWidget ); +} + +const KAboutData *SpecialdatesPlugin::aboutData() +{ + if ( !mAboutData ) { + mAboutData = new KAboutData( "specialdates", + I18N_NOOP( "Special Dates Summary" ), + "1.0", + I18N_NOOP( "Kontact Special Dates Summary" ), + KAboutData::License_LGPL, + I18N_NOOP( "(c) 2004-2005 The KDE PIM Team" ) ); + mAboutData->addAuthor( "Allen Winter", "Current Maintainer", "winter@kde.org" ); + mAboutData->addAuthor( "Tobias Koenig", "", "tokoe@kde.org" ); + mAboutData->setProductName( "kontact/specialdates" ); + } + + return mAboutData; +} diff --git a/kontact/plugins/specialdates/specialdates_plugin.h b/kontact/plugins/specialdates/specialdates_plugin.h new file mode 100644 index 000000000..6534afb5c --- /dev/null +++ b/kontact/plugins/specialdates/specialdates_plugin.h @@ -0,0 +1,52 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 Allen Winter <winter@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SPECIALDATES_PLUGIN_H +#define SPECIALDATES_PLUGIN_H + +#include "plugin.h" + +class SDSummaryWidget; + +class SpecialdatesPlugin : public Kontact::Plugin +{ + public: + SpecialdatesPlugin( Kontact::Core *core, const char *name, const QStringList& ); + ~SpecialdatesPlugin(); + + int weight() const { return 310; } + + const KAboutData *aboutData(); + + virtual Kontact::Summary *createSummaryWidget( QWidget *parentWidget ); + + protected: + virtual KParts::ReadOnlyPart *createPart() { return false; } + + private: + KAboutData *mAboutData; + +}; + +#endif diff --git a/kontact/plugins/specialdates/specialdatesplugin.desktop b/kontact/plugins/specialdates/specialdatesplugin.desktop new file mode 100644 index 000000000..bceb13ada --- /dev/null +++ b/kontact/plugins/specialdates/specialdatesplugin.desktop @@ -0,0 +1,92 @@ +[Desktop Entry] +Type=Service +Icon=cookie +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_specialdatesplugin +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPluginHasPart=false +X-KDE-KontactPluginHasSummary=true + +X-KDE-PluginInfo-Name=kontact_specialdatesplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +Name=Special Dates +Name[af]=Spesiale datums +Name[ar]=التواريخ المرقومة +Name[bg]=Специални случаи +Name[br]=Deiziadoù dibar +Name[ca]=Dates especials +Name[cs]=Speciální data +Name[da]=Særlige datoer +Name[de]=Besondere Termine +Name[el]=Σημαντικές ημερομηνίες +Name[eo]=Specialaj Datoj +Name[es]=Fechas especiales +Name[et]=Tähtpäevad +Name[eu]=Data bereziak +Name[fa]=تاریخهای ویژه +Name[fi]=Erikoispäivät +Name[fr]=Dates importantes +Name[fy]=Spesjale datums +Name[ga]=Dátaí Speisialta +Name[gl]=Datas Especiais +Name[he]=תאריכים מיוחדים +Name[hu]=Fontos dátumok +Name[is]=Sérstakir dagar +Name[it]=Date speciali +Name[ja]=特別な日 +Name[ka]=განსაკუტრებული თარიღები +Name[kk]=Ерекше күндер +Name[km]=ថ្ងៃពិសេស +Name[lt]=Ypatingos datos +Name[mk]=Специјални датуми +Name[ms]=Tarikh Khusus +Name[nb]=Spesielle datoer +Name[nds]=Besünner Daag +Name[ne]=विशेष मिति +Name[nl]=Speciale data +Name[nn]=Spesielle datoar +Name[pl]=Daty specjalne +Name[pt]=Datas Especiais +Name[pt_BR]=Datas Especiais +Name[ru]=Особые даты +Name[sk]=Špeciálne dátumy +Name[sl]=Posebni datumi +Name[sr]=Посебни датуми +Name[sr@Latn]=Posebni datumi +Name[sv]=Speciella datum +Name[ta]=விசேஷ தேதிகள் +Name[th]=วันพิเศษ +Name[tr]=Özel Tarihler +Name[uk]=Особливі дати +Name[uz]=Maxsus kunlar +Name[uz@cyrillic]=Махсус кунлар +Name[zh_CN]=特殊日期 +Name[zh_TW]=特殊日期 +Comment=Special Dates Component +Comment[bg]=Обобщение на специалните случаи +Comment[ca]=Component de dates especials +Comment[da]=Komponent til særlige datoer +Comment[de]=Komponente für Übersicht über besondere Termine +Comment[el]=Συστατικό σημαντικών ημερομηνιών +Comment[es]=Componente de fechas especiales +Comment[et]=Tähtpäevade plugin +Comment[fr]=Composant des dates importantes +Comment[is]=Eining fyrir sérstaka daga +Comment[it]=Componente per le date speciali +Comment[ja]=特別な日コンポーネント +Comment[km]=សមាសភាគកាលបរិច្ឆេទពិសេស +Comment[nds]=Komponent för besünner Daten +Comment[nl]=Component voor overzicht van speciale data +Comment[pl]=Składnik dat specjalnych +Comment[pt_BR]=Componente de Datas Especiais +Comment[ru]=Особые даты +Comment[sr]=Компонента посебних датума +Comment[sr@Latn]=Komponenta posebnih datuma +Comment[sv]=Speciella datumkomponent +Comment[tr]=Özel Tarihler Bileşeni +Comment[zh_CN]=特殊日期组件 +Comment[zh_TW]=特殊日期組件 diff --git a/kontact/plugins/summary/Makefile.am b/kontact/plugins/summary/Makefile.am new file mode 100644 index 000000000..ab83c72a5 --- /dev/null +++ b/kontact/plugins/summary/Makefile.am @@ -0,0 +1,26 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir)/certmanager/lib \ + -I$(top_srcdir)/libkdepim \ + -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_summaryplugin.la kcm_kontactsummary.la +libkontact_summaryplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_summaryplugin_la_LIBADD = -lkutils \ + $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) \ + $(top_builddir)/libkdepim/libkdepim.la $(top_builddir)/libkpimidentities/libkpimidentities.la + +libkontact_summaryplugin_la_SOURCES = summaryview_plugin.cpp summaryview_part.cpp dropwidget.cpp + +kcm_kontactsummary_la_SOURCES = kcmkontactsummary.cpp +kcm_kontactsummary_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) \ + -avoid-version -no-undefined +kcm_kontactsummary_la_LIBADD = $(LIB_KDEUI) $(LIB_KUTILS) + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = summaryplugin.desktop + +kde_services_DATA = kcmkontactsummary.desktop + +kpartrcdir = $(kde_datadir)/kontactsummary +kpartrc_DATA = kontactsummary_part.rc diff --git a/kontact/plugins/summary/dropwidget.cpp b/kontact/plugins/summary/dropwidget.cpp new file mode 100644 index 000000000..0d6aa5305 --- /dev/null +++ b/kontact/plugins/summary/dropwidget.cpp @@ -0,0 +1,44 @@ +/* + This file is part of KDE Kontact. + + Copyright (C) 2004 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qdragobject.h> + +#include "dropwidget.h" + +DropWidget::DropWidget( QWidget *parent, const char *name ) + : QWidget( parent, name ) +{ + setAcceptDrops( true ); +} + +void DropWidget::dragEnterEvent( QDragEnterEvent *event ) +{ + event->accept( QTextDrag::canDecode( event ) ); +} + +void DropWidget::dropEvent( QDropEvent *event ) +{ + int alignment = ( event->pos().x() < (width() / 2) ? Qt::AlignLeft : Qt::AlignRight ); + alignment |= ( event->pos().y() < (height() / 2) ? Qt::AlignTop : Qt::AlignBottom ); + emit summaryWidgetDropped( this, event->source(), alignment ); +} + +#include "dropwidget.moc" diff --git a/kontact/plugins/summary/dropwidget.h b/kontact/plugins/summary/dropwidget.h new file mode 100644 index 000000000..7cde7f5e0 --- /dev/null +++ b/kontact/plugins/summary/dropwidget.h @@ -0,0 +1,42 @@ +/* + This file is part of KDE Kontact. + + Copyright (C) 2004 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DROP_WIDGET_H +#define DROP_WIDGET_H + +#include <qwidget.h> + +class DropWidget : public QWidget +{ + Q_OBJECT + + public: + DropWidget( QWidget *parent, const char *name = 0 ); + + signals: + void summaryWidgetDropped( QWidget *target, QWidget *widget, int alignment ); + + protected: + virtual void dragEnterEvent( QDragEnterEvent* ); + virtual void dropEvent( QDropEvent* ); +}; + +#endif diff --git a/kontact/plugins/summary/kcmkontactsummary.cpp b/kontact/plugins/summary/kcmkontactsummary.cpp new file mode 100644 index 000000000..d52d991fc --- /dev/null +++ b/kontact/plugins/summary/kcmkontactsummary.cpp @@ -0,0 +1,189 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <kaboutdata.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialog.h> +#include <kiconloader.h> +#include <kiconloader.h> +#include <klocale.h> +#include <plugin.h> +#include <kplugininfo.h> +#include <ktrader.h> + +#include <qlayout.h> +#include <qlabel.h> +#include <qpixmap.h> + +#include "kcmkontactsummary.h" + +#include <kdepimmacros.h> + +extern "C" +{ + KDE_EXPORT KCModule *create_kontactsummary( QWidget *parent, const char * ) { + return new KCMKontactSummary( parent, "kcmkontactsummary" ); + } +} + +class PluginItem : public QCheckListItem +{ + public: + PluginItem( KPluginInfo *info, KListView *parent ) + : QCheckListItem( parent, QString::null, QCheckListItem::CheckBox ), + mInfo( info ) + { + QPixmap pm = KGlobal::iconLoader()->loadIcon( mInfo->icon(), KIcon::Small ); + setPixmap( 0, pm ); + } + + KPluginInfo* pluginInfo() const + { + return mInfo; + } + + virtual QString text( int column ) const + { + if ( column == 0 ) + return mInfo->name(); + else if ( column == 1 ) + return mInfo->comment(); + else + return QString::null; + } + + private: + KPluginInfo *mInfo; +}; + +PluginView::PluginView( QWidget *parent, const char *name ) + : KListView( parent, name ) +{ + addColumn( i18n( "Name" ) ); + setAllColumnsShowFocus( true ); + setFullWidth( true ); +} + +PluginView::~PluginView() +{ +} + +KCMKontactSummary::KCMKontactSummary( QWidget *parent, const char *name ) + : KCModule( parent, name ) +{ + QVBoxLayout *layout = new QVBoxLayout( this, 0, KDialog::spacingHint() ); + + QLabel *label = new QLabel( i18n( "Here you can select which summary plugins to have visible in your summary view." ), this ); + layout->addWidget( label ); + + mPluginView = new PluginView( this ); + layout->addWidget( mPluginView ); + + layout->setStretchFactor( mPluginView, 1 ); + + connect( mPluginView, SIGNAL( clicked( QListViewItem* ) ), + this, SLOT( itemClicked( QListViewItem* ) ) ); + load(); + + KAboutData *about = new KAboutData( I18N_NOOP( "kontactsummary" ), + I18N_NOOP( "KDE Kontact Summary" ), + 0, 0, KAboutData::License_GPL, + I18N_NOOP( "(c), 2004 Tobias Koenig" ) ); + + about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" ); + setAboutData( about ); +} + +void KCMKontactSummary::load() +{ + KTrader::OfferList offers = KTrader::self()->query( + QString::fromLatin1( "Kontact/Plugin" ), + QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) ); + + QStringList activeSummaries; + + KConfig config( "kontact_summaryrc" ); + if ( !config.hasKey( "ActiveSummaries" ) ) { + activeSummaries << "kontact_kaddressbookplugin"; + activeSummaries << "kontact_specialdatesplugin"; + activeSummaries << "kontact_korganizerplugin"; + activeSummaries << "kontact_todoplugin"; + activeSummaries << "kontact_kpilotplugin"; + activeSummaries << "kontact_weatherplugin"; + activeSummaries << "kontact_newstickerplugin"; + } else { + activeSummaries = config.readListEntry( "ActiveSummaries" ); + } + + mPluginView->clear(); + mPluginList.clear(); + + mPluginList = KPluginInfo::fromServices( offers, &config, "Plugins" ); + KPluginInfo::List::Iterator it; + for ( it = mPluginList.begin(); it != mPluginList.end(); ++it ) { + (*it)->load(); + + if ( !(*it)->isPluginEnabled() ) + continue; + + QVariant var = (*it)->property( "X-KDE-KontactPluginHasSummary" ); + if ( !var.isValid() ) + continue; + + if ( var.toBool() == true ) { + PluginItem *item = new PluginItem( *it, mPluginView ); + + if ( activeSummaries.find( (*it)->pluginName() ) != activeSummaries.end() ) + item->setOn( true ); + } + } +} + +void KCMKontactSummary::save() +{ + QStringList activeSummaries; + + QListViewItemIterator it( mPluginView, QListViewItemIterator::Checked ); + while ( it.current() ) { + PluginItem *item = static_cast<PluginItem*>( it.current() ); + activeSummaries.append( item->pluginInfo()->pluginName() ); + ++it; + } + + KConfig config( "kontact_summaryrc" ); + config.writeEntry( "ActiveSummaries", activeSummaries ); +} + +void KCMKontactSummary::defaults() +{ + emit changed( true ); +} + +void KCMKontactSummary::itemClicked( QListViewItem* ) +{ + emit changed( true ); +} + +#include "kcmkontactsummary.moc" diff --git a/kontact/plugins/summary/kcmkontactsummary.desktop b/kontact/plugins/summary/kcmkontactsummary.desktop new file mode 100644 index 000000000..5442d5c0b --- /dev/null +++ b/kontact/plugins/summary/kcmkontactsummary.desktop @@ -0,0 +1,79 @@ +[Desktop Entry] +Icon=kontact_summary +Type=Service +ServiceTypes=KCModule + +X-KDE-ModuleType=Library +X-KDE-Library=kontactsummary +X-KDE-FactoryName=kontactsummary +X-KDE-ParentApp=kontact_summaryplugin +X-KDE-ParentComponents=kontact_summaryplugin +X-KDE-CfgDlgHierarchy=KontactSummary + +Name=Summary View Items +Name[bg]=Обобщение +Name[ca]=Vista resum d'elements +Name[da]=Elementer i opsummeringsvisning +Name[de]=Elemente der Zusammenfassungsansicht +Name[el]=Αντικείμενα προβολής σύνοψης +Name[es]=Elementos de la vista de sumario +Name[et]=Kokkuvõttevaate elemendid +Name[it]=Elementi vista sommario +Name[ja]=要約ビューの項目 +Name[km]=ធាតុទិដ្ឋភាពសង្ខេប +Name[nds]=Översicht-Indrääg +Name[nl]=Overzichtsweergave-items +Name[pl]=Elementy widoku podsumowania +Name[sr]=Ставке приказа сажетка +Name[sr@Latn]=Stavke prikaza sažetka +Name[sv]=Objekt i översiktsvy +Name[tr]=Özet Görünüm Ögeleri +Name[zh_CN]=摘要视图项目 +Name[zh_TW]=摘要檢視項目 +Comment=General Configuration of Kontact's Summary View +Comment[af]=Algemene opstelling van Kontact se opsomming aansig +Comment[bg]=Настройка на обобщението +Comment[bs]=Opšte podešavanje Kontactovog prozora Sažetak +Comment[ca]=Configuració general de la vista de resum del Kontact +Comment[cs]=Obecné nastavení souhrnného pohledu pro Kontact +Comment[da]=Generel indstilling af Kontact's sammendragsvisning +Comment[de]=Allgemeine Einstellungen für die Übersichtsansicht von Kontact +Comment[el]=Γενικές ρυθμίσεις της Προβολής Σύνοψης του Kontact +Comment[es]=Configuración general de la vista del resumen de Kontact +Comment[et]=Kontacti kokkuvõttevaate üldised seadistused +Comment[eu]=Kontact-en laburpen ikuspegiaren konfigurazio orokorra +Comment[fa]=پیکربندی عمومی نمای خلاصۀ Kontact +Comment[fi]=Kontactin yhteenvetonäkymän yleiset asetukset +Comment[fr]=Configuration générale de la vue résumée de Kontact +Comment[fy]=Algemiene ynstellings fan Kontact's oersichtswerjefte +Comment[gl]=Configuración xeral para a vista de resumo de Kontact +Comment[hu]=A Kontact áttekintő nézetének beállításai +Comment[is]=Almennar stillingar fyrir Kontact yfirlitssýn +Comment[it]=Configurazione generale della vista sommario di Kontact +Comment[ja]=Kontact の要約表示の一般的な設定 +Comment[ka]=Kontact დაიჯესტის ხედის ზოგადი პარამეტრები +Comment[kk]=Тұжырымдаманың жалпы параметрлері +Comment[km]=ការកំណត់រចនាសម្ព័ន្ធទូទៅនៃទិដ្ឋភាពសង្ខេបរបស់ Kontact +Comment[lt]=Kontact Santraukos vaizdo bendrasis konfigūravimas +Comment[mk]=Општа конфигурација на прегледот на Контакт +Comment[ms]=Konfigurasi Am Paparan Ringkasan Kontact +Comment[nb]=Generelt oppsett av Kontact's sammendragsoversikt +Comment[nds]=Allgemeen Instellen för de Översichtansicht von Kontact +Comment[ne]=सम्पर्कको सारांश दृश्यको साधारण कन्फिगरेसन +Comment[nl]=Algemene instellingen van Kontact's overzichtsweergave +Comment[nn]=Generelt oppsett av samandragsvisinga i Kontact +Comment[pl]=Ogólna konfiguracja widoku podsumowania w Kontact +Comment[pt]=Configuração Geral da Vista Sumária do Kontact +Comment[pt_BR]=Configuração Geral da Visão de Resumo do Kontact +Comment[ru]=Настройка сводок Kontact +Comment[sk]=Všeobecné nastavenie súhrnu Kontact +Comment[sl]=Splošne nastavitve za prikaz povzetka v Kontract +Comment[sr]=Опште подешавање Kontact-овог приказа сажетка +Comment[sr@Latn]=Opšte podešavanje Kontact-ovog prikaza sažetka +Comment[sv]=Allmän inställning av Kontacts översiktsvy +Comment[ta]=கான்டாக்கின் சுருக்க காட்சியின் பொது கட்டமைப்பு +Comment[tg]=Танзимотҳои умумии дайджести Kontact +Comment[tr]=Kontact'ın Özet Görünümü için Genel Yapılandırma +Comment[uk]=Загальні параметри підсумків Kontact +Comment[zh_CN]=Kontact 概览视图的常规配置 +Comment[zh_TW]=Kontacts 摘要檢視的一般設定 diff --git a/kontact/plugins/summary/kcmkontactsummary.h b/kontact/plugins/summary/kcmkontactsummary.h new file mode 100644 index 000000000..3c6c6d05d --- /dev/null +++ b/kontact/plugins/summary/kcmkontactsummary.h @@ -0,0 +1,62 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KCMKONTACTSUMMARY_H +#define KCMKONTACTSUMMARY_H + +#include <kcmodule.h> +#include <klistview.h> + +class KPluginInfo; + +class PluginView : public KListView +{ + Q_OBJECT + + public: + PluginView( QWidget *parent, const char *name = 0 ); + ~PluginView(); +}; + +class KCMKontactSummary : public KCModule +{ + Q_OBJECT + + public: + KCMKontactSummary( QWidget *parent = 0, const char *name = 0 ); + + virtual void load(); + virtual void save(); + virtual void defaults(); + + private slots: + void itemClicked( QListViewItem* ); + + private: + PluginView *mPluginView; + + KPluginInfo::List mPluginList; +}; + +#endif diff --git a/kontact/plugins/summary/kontactsummary_part.rc b/kontact/plugins/summary/kontactsummary_part.rc new file mode 100644 index 000000000..9c121426c --- /dev/null +++ b/kontact/plugins/summary/kontactsummary_part.rc @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="kontactsummary" version="3"> + <MenuBar> + <Menu name="settings"><text>&Settings</text> + <Action name="summaryview_configure" group="settings_configure"/> + </Menu> + </MenuBar> +</gui> diff --git a/kontact/plugins/summary/summaryplugin.desktop b/kontact/plugins/summary/summaryplugin.desktop new file mode 100644 index 000000000..d2aa1c956 --- /dev/null +++ b/kontact/plugins/summary/summaryplugin.desktop @@ -0,0 +1,97 @@ +[Desktop Entry] +Type=Service +Icon=kontact_summary +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkontact_summaryplugin +X-KDE-KontactPluginVersion=6 + +X-KDE-PluginInfo-Name=kontact_summaryplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Summary View Component +Comment[bg]=Обобщение +Comment[ca]=Component de vista resum +Comment[da]=Komponent for opsummeringsvisning +Comment[de]=Zusammenfassungsansicht-Komponente +Comment[el]=Συστατικό προβολής σύνοψης +Comment[es]=Componente Vista de resumen +Comment[et]=Kokkuvõttevaate plugin +Comment[fr]=Composant de la vue résumée +Comment[is]=Eining fyrir yfirlitssýn +Comment[it]=Componente vista sommario +Comment[ja]=要約ビューコンポーネント +Comment[km]=សមាសភាគទិដ្ឋភាពសង្ខេប +Comment[nds]=Översicht-Komponent +Comment[nl]=Overzichtsweergaveitem +Comment[pl]=Składnik widoku podsumowania +Comment[ru]=Просмотр сводок +Comment[sr]=Компонента приказа сажетка +Comment[sr@Latn]=Komponenta prikaza sažetka +Comment[sv]=Översiktsvykomponent +Comment[tr]=Özet Görünüm Bileşeni +Comment[zh_CN]=摘要视图组件 +Comment[zh_TW]=摘要檢視組件 +Name=Summary +Name[af]=Opsomming +Name[ar]=الموجز +Name[bg]=Обобщение +Name[br]=Diverrañ +Name[bs]=Sažetak +Name[ca]=Resum +Name[cs]=Souhrn +Name[cy]=Crynodeb +Name[da]=Opsummering +Name[de]=Übersicht +Name[el]=Σύνοψη +Name[eo]=Resumo +Name[es]=Resumen +Name[et]=Kokkuvõte +Name[eu]=Laburpena +Name[fa]=خلاصه +Name[fi]=Yhteenveto +Name[fr]=Résumé +Name[fy]=Oersicht +Name[ga]=Achoimre +Name[gl]=Resumo +Name[he]=תקציר +Name[hi]=सारांश +Name[hu]=Áttekintő +Name[is]=Yfirlit +Name[it]=Sommario +Name[ja]=要約 +Name[ka]=დაიჯესტი +Name[kk]=Тұжырым +Name[km]=សង្ខេប +Name[lt]=Santrauka +Name[mk]=Преглед +Name[ms]=Ringkasan +Name[nb]=Sammendrag +Name[nds]=Översicht +Name[ne]=सारांश +Name[nl]=Overzicht +Name[nn]=Samandrag +Name[pl]=Podsumowanie +Name[pt]=Resumo +Name[pt_BR]=Resumo +Name[ro]=Sumar +Name[ru]=Сводки +Name[se]=Čoahkkáigeassu +Name[sk]=Súhrn +Name[sl]=Povzetek +Name[sr]=Сажетак +Name[sr@Latn]=Sažetak +Name[sv]=Översikt +Name[ta]=சுருக்கம் +Name[tg]=Дайджест +Name[th]=หน้าสรุป +Name[tr]=Özet +Name[uk]=Зведення +Name[uz]=Hisobot +Name[uz@cyrillic]=Ҳисобот +Name[zh_CN]=概览 +Name[zh_TW]=摘要 +#Always last +InitialPreference=0 diff --git a/kontact/plugins/summary/summaryview_part.cpp b/kontact/plugins/summary/summaryview_part.cpp new file mode 100644 index 000000000..9597de674 --- /dev/null +++ b/kontact/plugins/summary/summaryview_part.cpp @@ -0,0 +1,434 @@ +/* + This file is part of KDE Kontact. + + Copyright (C) 2003 Sven Lüppken <sven@kde.org> + Copyright (C) 2003 Tobias König <tokoe@kde.org> + Copyright (C) 2003 Daniel Molkentin <molkentin@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qframe.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtimer.h> + +#include <dcopclient.h> +#include <kaction.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kdcopservicestarter.h> +#include <kdebug.h> +#include <kdialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kservice.h> +#include <ktrader.h> +#include <kstandarddirs.h> +#include <qscrollview.h> +#include <kglobal.h> +#include <klocale.h> +#include <kcmultidialog.h> + +#include <kparts/componentfactory.h> +#include <kparts/event.h> + +#include <libkpimidentities/identity.h> +#include <libkpimidentities/identitymanager.h> + +#include <infoextension.h> +#include <sidebarextension.h> + +#include "plugin.h" +#include "summary.h" + +#include "summaryview_part.h" + +#include "broadcaststatus.h" +using KPIM::BroadcastStatus; + +namespace Kontact +{ + class MainWindow; +} + +SummaryViewPart::SummaryViewPart( Kontact::Core *core, const char*, + const KAboutData *aboutData, + QObject *parent, const char *name ) + : KParts::ReadOnlyPart( parent, name ), + mCore( core ), mFrame( 0 ), mConfigAction( 0 ) +{ + setInstance( new KInstance( aboutData ) ); + + loadLayout(); + + initGUI( core ); + + connect( kapp, SIGNAL( kdisplayPaletteChanged() ), SLOT( slotAdjustPalette() ) ); + slotAdjustPalette(); + + setDate( QDate::currentDate() ); + connect( mCore, SIGNAL( dayChanged( const QDate& ) ), + SLOT( setDate( const QDate& ) ) ); + + KParts::InfoExtension *info = new KParts::InfoExtension( this, "Summary" ); + connect( this, SIGNAL( textChanged( const QString& ) ), + info, SIGNAL( textChanged( const QString& ) ) ); + + mConfigAction = new KAction( i18n( "&Configure Summary View..." ), + "configure", 0, this, + SLOT( slotConfigure() ), actionCollection(), + "summaryview_configure" ); + + setXMLFile( "kontactsummary_part.rc" ); + + QTimer::singleShot( 0, this, SLOT( slotTextChanged() ) ); +} + +SummaryViewPart::~SummaryViewPart() +{ + saveLayout(); +} + +bool SummaryViewPart::openFile() +{ + kdDebug(5006) << "SummaryViewPart:openFile()" << endl; + return true; +} + +void SummaryViewPart::partActivateEvent( KParts::PartActivateEvent *event ) +{ + // inform the plugins that the part has been activated so that they can + // update the displayed information + if ( event->activated() && ( event->part() == this ) ) { + updateSummaries(); + } + + KParts::ReadOnlyPart::partActivateEvent( event ); +} + +void SummaryViewPart::updateSummaries() +{ + QMap<QString, Kontact::Summary*>::Iterator it; + for ( it = mSummaries.begin(); it != mSummaries.end(); ++it ) + it.data()->updateSummary( false ); +} + +void SummaryViewPart::updateWidgets() +{ + mMainWidget->setUpdatesEnabled( false ); + + delete mFrame; + + KPIM::IdentityManager idm( true, this ); + const KPIM::Identity &id = idm.defaultIdentity(); + + QString currentUser = i18n( "Summary for %1" ).arg( id.fullName() ); + mUsernameLabel->setText( QString::fromLatin1( "<b>%1</b>" ).arg( currentUser ) ); + + mSummaries.clear(); + + mFrame = new DropWidget( mMainWidget ); + connect( mFrame, SIGNAL( summaryWidgetDropped( QWidget*, QWidget*, int ) ), + this, SLOT( summaryWidgetMoved( QWidget*, QWidget*, int ) ) ); + + mMainLayout->insertWidget( 2, mFrame ); + + QStringList activeSummaries; + + KConfig config( "kontact_summaryrc" ); + if ( !config.hasKey( "ActiveSummaries" ) ) { + activeSummaries << "kontact_kmailplugin"; + activeSummaries << "kontact_specialdatesplugin"; + activeSummaries << "kontact_korganizerplugin"; + activeSummaries << "kontact_todoplugin"; + activeSummaries << "kontact_newstickerplugin"; + } else { + activeSummaries = config.readListEntry( "ActiveSummaries" ); + } + + // Collect all summary widgets with a summaryHeight > 0 + QStringList loadedSummaries; + + QValueList<Kontact::Plugin*> plugins = mCore->pluginList(); + QValueList<Kontact::Plugin*>::ConstIterator end = plugins.end(); + QValueList<Kontact::Plugin*>::ConstIterator it = plugins.begin(); + for ( ; it != end; ++it ) { + Kontact::Plugin *plugin = *it; + if ( activeSummaries.find( plugin->identifier() ) == activeSummaries.end() ) + continue; + + Kontact::Summary *summary = plugin->createSummaryWidget( mFrame ); + if ( summary ) { + if ( summary->summaryHeight() > 0 ) { + mSummaries.insert( plugin->identifier(), summary ); + + connect( summary, SIGNAL( message( const QString& ) ), + BroadcastStatus::instance(), SLOT( setStatusMsg( const QString& ) ) ); + connect( summary, SIGNAL( summaryWidgetDropped( QWidget*, QWidget*, int ) ), + this, SLOT( summaryWidgetMoved( QWidget*, QWidget*, int ) ) ); + + if ( !mLeftColumnSummaries.contains( plugin->identifier() ) && + !mRightColumnSummaries.contains( plugin->identifier() ) ) { + mLeftColumnSummaries.append( plugin->identifier() ); + } + + loadedSummaries.append( plugin->identifier() ); + } else { + summary->hide(); + } + } + } + + // Remove all unavailable summary widgets + { + QStringList::Iterator strIt; + for ( strIt = mLeftColumnSummaries.begin(); strIt != mLeftColumnSummaries.end(); ++strIt ) { + if ( loadedSummaries.find( *strIt ) == loadedSummaries.end() ) { + strIt = mLeftColumnSummaries.remove( strIt ); + --strIt; + } + } + for ( strIt = mRightColumnSummaries.begin(); strIt != mRightColumnSummaries.end(); ++strIt ) { + if ( loadedSummaries.find( *strIt ) == loadedSummaries.end() ) { + strIt = mRightColumnSummaries.remove( strIt ); + --strIt; + } + } + } + + // Add vertical line between the two rows of summary widgets. + QFrame *vline = new QFrame( mFrame ); + vline->setFrameStyle( QFrame::VLine | QFrame::Plain ); + + QHBoxLayout *layout = new QHBoxLayout( mFrame ); + + mLeftColumn = new QVBoxLayout( layout, KDialog::spacingHint() ); + layout->addWidget( vline ); + mRightColumn = new QVBoxLayout( layout, KDialog::spacingHint() ); + + + QStringList::Iterator strIt; + for ( strIt = mLeftColumnSummaries.begin(); strIt != mLeftColumnSummaries.end(); ++strIt ) { + if ( mSummaries.find( *strIt ) != mSummaries.end() ) + mLeftColumn->addWidget( mSummaries[ *strIt ] ); + } + + for ( strIt = mRightColumnSummaries.begin(); strIt != mRightColumnSummaries.end(); ++strIt ) { + if ( mSummaries.find( *strIt ) != mSummaries.end() ) + mRightColumn->addWidget( mSummaries[ *strIt ] ); + } + + mFrame->show(); + + mMainWidget->setUpdatesEnabled( true ); + mMainWidget->update(); + + mLeftColumn->addStretch(); + mRightColumn->addStretch(); +} + +void SummaryViewPart::summaryWidgetMoved( QWidget *target, QWidget *widget, int alignment ) +{ + if ( target == widget ) + return; + + if ( target == mFrame ) { + if ( mLeftColumn->findWidget( widget ) == -1 && mRightColumn->findWidget( widget ) == -1 ) + return; + } else { + if ( mLeftColumn->findWidget( target ) == -1 && mRightColumn->findWidget( target ) == -1 || + mLeftColumn->findWidget( widget ) == -1 && mRightColumn->findWidget( widget ) == -1 ) + return; + } + + if ( mLeftColumn->findWidget( widget ) != -1 ) { + mLeftColumn->remove( widget ); + mLeftColumnSummaries.remove( widgetName( widget ) ); + } else if ( mRightColumn->findWidget( widget ) != -1 ) { + mRightColumn->remove( widget ); + mRightColumnSummaries.remove( widgetName( widget ) ); + } + + if ( target == mFrame ) { + int pos = 0; + + if ( alignment & Qt::AlignTop ) + pos = 0; + + if ( alignment & Qt::AlignLeft ) { + if ( alignment & Qt::AlignBottom ) + pos = mLeftColumnSummaries.count(); + + mLeftColumn->insertWidget( pos, widget ); + mLeftColumnSummaries.insert( mLeftColumnSummaries.at( pos ), widgetName( widget ) ); + } else { + if ( alignment & Qt::AlignBottom ) + pos = mRightColumnSummaries.count(); + + mRightColumn->insertWidget( pos, widget ); + mRightColumnSummaries.insert( mRightColumnSummaries.at( pos ), widgetName( widget ) ); + } + + return; + } + + int targetPos = mLeftColumn->findWidget( target ); + if ( targetPos != -1 ) { + if ( alignment == Qt::AlignBottom ) + targetPos++; + + mLeftColumn->insertWidget( targetPos, widget ); + mLeftColumnSummaries.insert( mLeftColumnSummaries.at( targetPos ), widgetName( widget ) ); + } else { + targetPos = mRightColumn->findWidget( target ); + + if ( alignment == Qt::AlignBottom ) + targetPos++; + + mRightColumn->insertWidget( targetPos, widget ); + mRightColumnSummaries.insert( mRightColumnSummaries.at( targetPos ), widgetName( widget ) ); + } +} + +void SummaryViewPart::slotTextChanged() +{ + emit textChanged( i18n( "What's next?" ) ); +} + +void SummaryViewPart::slotAdjustPalette() +{ + mMainWidget->setPaletteBackgroundColor( kapp->palette().active().base() ); +} + +void SummaryViewPart::setDate( const QDate& newDate ) +{ + QString date( "<b>%1</b>" ); + date = date.arg( KGlobal::locale()->formatDate( newDate ) ); + mDateLabel->setText( date ); +} + +void SummaryViewPart::slotConfigure() +{ + KCMultiDialog dlg( mMainWidget, "ConfigDialog", true ); + + QStringList modules = configModules(); + modules.prepend( "kcmkontactsummary.desktop" ); + connect( &dlg, SIGNAL( configCommitted() ), + this, SLOT( updateWidgets() ) ); + + QStringList::ConstIterator strIt; + for ( strIt = modules.begin(); strIt != modules.end(); ++strIt ) + dlg.addModule( *strIt ); + + dlg.exec(); +} + +QStringList SummaryViewPart::configModules() const +{ + QStringList modules; + + QMap<QString, Kontact::Summary*>::ConstIterator it; + for ( it = mSummaries.begin(); it != mSummaries.end(); ++it ) { + QStringList cm = it.data()->configModules(); + QStringList::ConstIterator strIt; + for ( strIt = cm.begin(); strIt != cm.end(); ++strIt ) + if ( !(*strIt).isEmpty() && !modules.contains( *strIt ) ) + modules.append( *strIt ); + } + + return modules; +} + +void SummaryViewPart::initGUI( Kontact::Core *core ) +{ + QScrollView *sv = new QScrollView( core ); + + sv->setResizePolicy( QScrollView::AutoOneFit ); + sv->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); + sv->setHScrollBarMode( QScrollView::AlwaysOff ); + + mMainWidget = new QFrame( sv->viewport() ); + sv->addChild( mMainWidget ); + mMainWidget->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + sv->setFocusPolicy( QWidget::StrongFocus ); + setWidget( sv ); + + mMainLayout = new QVBoxLayout( mMainWidget,KDialog::marginHint(), + KDialog::spacingHint() ); + + QHBoxLayout *hbl = new QHBoxLayout( mMainLayout ); + mUsernameLabel = new QLabel( mMainWidget ); + hbl->addWidget( mUsernameLabel ); + mDateLabel = new QLabel( mMainWidget ); + mDateLabel->setAlignment( AlignRight ); + hbl->addWidget( mDateLabel ); + + QFrame *hline = new QFrame( mMainWidget ); + hline->setFrameStyle( QFrame::HLine | QFrame::Plain ); + mMainLayout->insertWidget( 1, hline ); + + mFrame = new DropWidget( mMainWidget ); + mMainLayout->insertWidget( 2, mFrame ); + + connect( mFrame, SIGNAL( summaryWidgetDropped( QWidget*, QWidget*, int ) ), + this, SLOT( summaryWidgetMoved( QWidget*, QWidget*, int ) ) ); + + updateWidgets(); +} + +void SummaryViewPart::loadLayout() +{ + KConfig config( "kontact_summaryrc" ); + + if ( !config.hasKey( "LeftColumnSummaries" ) ) { + mLeftColumnSummaries << "kontact_korganizerplugin"; + mLeftColumnSummaries << "kontact_todoplugin"; + mLeftColumnSummaries << "kontact_kaddressbookplugin"; + mLeftColumnSummaries << "kontact_specialdatesplugin"; + } else { + mLeftColumnSummaries = config.readListEntry( "LeftColumnSummaries" ); + } + + if ( !config.hasKey( "RightColumnSummaries" ) ) { + mRightColumnSummaries << "kontact_newstickerplugin"; + } else { + mRightColumnSummaries = config.readListEntry( "RightColumnSummaries" ); + } +} + +void SummaryViewPart::saveLayout() +{ + KConfig config( "kontact_summaryrc" ); + + config.writeEntry( "LeftColumnSummaries", mLeftColumnSummaries ); + config.writeEntry( "RightColumnSummaries", mRightColumnSummaries ); + + config.sync(); +} + +QString SummaryViewPart::widgetName( QWidget *widget ) const +{ + QMap<QString, Kontact::Summary*>::ConstIterator it; + for ( it = mSummaries.begin(); it != mSummaries.end(); ++it ) { + if ( it.data() == widget ) + return it.key(); + } + + return QString::null; +} + +#include "summaryview_part.moc" diff --git a/kontact/plugins/summary/summaryview_part.h b/kontact/plugins/summary/summaryview_part.h new file mode 100644 index 000000000..f98d7d065 --- /dev/null +++ b/kontact/plugins/summary/summaryview_part.h @@ -0,0 +1,103 @@ +/* + This file is part of KDE Kontact. + + Copyright (C) 2003 Sven Lüppken <sven@kde.org> + Copyright (C) 2003 Tobias König <tokoe@kde.org> + Copyright (C) 2003 Daniel Molkentin <molkentin@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SUMMARYVIEW_PART_H +#define SUMMARYVIEW_PART_H + +#include <qdatetime.h> +#include <qmap.h> + +#include <kparts/part.h> + +#include "core.h" +#include "dropwidget.h" + +namespace Kontact +{ + class Plugin; + class Summary; +} + +namespace KParts +{ + class PartActivateEvent; +} + +class QFrame; +class QLabel; +class QGridLayout; +class KAction; +class KCMultiDialog; + +class SummaryViewPart : public KParts::ReadOnlyPart +{ + Q_OBJECT + + public: + SummaryViewPart( Kontact::Core *core, const char *widgetName, + const KAboutData *aboutData, + QObject *parent = 0, const char *name = 0 ); + ~SummaryViewPart(); + + public slots: + void slotTextChanged(); + void slotAdjustPalette(); + void setDate( const QDate& newDate ); + void updateSummaries(); + + signals: + void textChanged( const QString& ); + + protected: + virtual bool openFile(); + virtual void partActivateEvent( KParts::PartActivateEvent *event ); + + protected slots: + void slotConfigure(); + void updateWidgets(); + void summaryWidgetMoved( QWidget *target, QWidget *widget, int alignment ); + + private: + void initGUI( Kontact::Core *core ); + void loadLayout(); + void saveLayout(); + QString widgetName( QWidget* ) const; + + QStringList configModules() const; + + QMap<QString, Kontact::Summary*> mSummaries; + Kontact::Core *mCore; + DropWidget *mFrame; + QFrame *mMainWidget; + QVBoxLayout *mMainLayout; + QVBoxLayout *mLeftColumn; + QVBoxLayout *mRightColumn; + QLabel *mUsernameLabel; + QLabel *mDateLabel; + KAction *mConfigAction; + + QStringList mLeftColumnSummaries; + QStringList mRightColumnSummaries; +}; + +#endif diff --git a/kontact/plugins/summary/summaryview_plugin.cpp b/kontact/plugins/summary/summaryview_plugin.cpp new file mode 100644 index 000000000..a73faf7e0 --- /dev/null +++ b/kontact/plugins/summary/summaryview_plugin.cpp @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Sven L�ppken <sven@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "summaryview_plugin.h" +#include "core.h" +#include "summaryview_part.h" + +#include <dcopref.h> +#include <kgenericfactory.h> +#include <kparts/componentfactory.h> +#include <kaboutdata.h> +#include <kaction.h> + +#include <qpopupmenu.h> + +typedef KGenericFactory< SummaryView, Kontact::Core > SummaryViewFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_summaryplugin, + SummaryViewFactory( "kontact_summaryplugin" ) ) + +SummaryView::SummaryView( Kontact::Core *core, const char *name, const QStringList& ) + : Kontact::Plugin( core, core, name), + mAboutData( 0 ), mPart( 0 ) +{ + setInstance( SummaryViewFactory::instance() ); + + mSyncAction = new KSelectAction( i18n( "Synchronize All" ), "reload", 0, this, + SLOT( doSync() ), actionCollection(), + "kontact_summary_sync" ); + connect( mSyncAction, SIGNAL( activated( const QString& ) ), this, SLOT( syncAccount( const QString& ) ) ); + connect( mSyncAction->popupMenu(), SIGNAL( aboutToShow() ), this, SLOT( fillSyncActionSubEntries() ) ); + + insertSyncAction( mSyncAction ); + fillSyncActionSubEntries(); +} + +void SummaryView::fillSyncActionSubEntries() +{ + QStringList menuItems; + menuItems.append( i18n("All") ); + + DCOPRef ref( "kmail", "KMailIface" ); + DCOPReply reply = ref.call( "accounts" ); + + if ( reply.isValid() ) + { + const QStringList accounts = reply; + menuItems += accounts; + } + mSyncAction->clear(); + mSyncAction->setItems( menuItems ); +} + +void SummaryView::syncAccount( const QString& account ) +{ + const QString acc = account == i18n("All") ? QString() : account; + DCOPRef ref( "kmail", "KMailIface" ); + ref.send( "checkAccount", acc ); + fillSyncActionSubEntries(); +} + +SummaryView::~SummaryView() +{ +} + +void SummaryView::doSync() +{ + if ( mPart ) + mPart->updateSummaries(); + + const QValueList<Kontact::Plugin*> pluginList = core()->pluginList(); + for ( QValueList<Kontact::Plugin*>::ConstIterator it = pluginList.begin(), end = pluginList.end(); + it != end; ++it ) { + // execute all sync actions but our own + QPtrList<KAction> *actions = (*it)->syncActions(); + for ( QPtrList<KAction>::Iterator jt = actions->begin(), end = actions->end(); jt != end; ++jt ) { + if ( *jt != mSyncAction ) + (*jt)->activate(); + } + } + fillSyncActionSubEntries(); +} + +KParts::ReadOnlyPart *SummaryView::createPart() +{ + mPart = new SummaryViewPart( core(), "summarypartframe", aboutData(), + this, "summarypart" ); + return mPart; +} + +const KAboutData *SummaryView::aboutData() +{ + if ( !mAboutData ) { + mAboutData = new KAboutData( "kontactsummary", I18N_NOOP("Kontact Summary"), + "1.1", + I18N_NOOP("Kontact Summary View"), + KAboutData::License_LGPL, + I18N_NOOP("(c) 2003 The Kontact developers" ) ); + mAboutData->addAuthor( "Sven Lueppken", "", "sven@kde.org" ); + mAboutData->addAuthor( "Cornelius Schumacher", "", "schumacher@kde.org" ); + mAboutData->addAuthor( "Tobias Koenig", "", "tokoe@kde.org" ); + mAboutData->setProductName( "kontact/summary" ); + } + + return mAboutData; +} + +#include "summaryview_plugin.moc" diff --git a/kontact/plugins/summary/summaryview_plugin.h b/kontact/plugins/summary/summaryview_plugin.h new file mode 100644 index 000000000..9093a1b34 --- /dev/null +++ b/kontact/plugins/summary/summaryview_plugin.h @@ -0,0 +1,62 @@ +/* + This file is part of KDE Kontact. + + Copyright (C) 2003 Sven L�ppken <sven@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SUMMARYVIEW_PLUGIN_H +#define SUMMARYVIEW_PLUGIN_H +#include "plugin.h" + +#include <klocale.h> +#include <kparts/part.h> + +#include <qmap.h> + +class KSelectAction; + +class SummaryViewPart; + +class SummaryView : public Kontact::Plugin +{ + Q_OBJECT + + public: + SummaryView( Kontact::Core *core, const char *name, const QStringList& ); + ~SummaryView(); + + int weight() const { return 100; } + + const KAboutData *aboutData(); + + protected: + virtual KParts::ReadOnlyPart* createPart(); + + private slots: + + void doSync(); + void syncAccount( const QString& account ); + void fillSyncActionSubEntries(); + + private: + KAboutData *mAboutData; + SummaryViewPart *mPart; + KSelectAction *mSyncAction; +}; + +#endif diff --git a/kontact/plugins/test/Makefile.am b/kontact/plugins/test/Makefile.am new file mode 100644 index 000000000..3fbac9eb3 --- /dev/null +++ b/kontact/plugins/test/Makefile.am @@ -0,0 +1,20 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces $(all_includes) + +kde_module_LTLIBRARIES = libkptestplugin.la +libkptestplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkptestplugin_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) + +libkptestplugin_la_SOURCES = test_plugin.cpp test_part.cpp kaddressbookiface.stub + +kaddressbookiface_DIR = $(top_srcdir)/kaddressbook + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kptestplugin.desktop + +rc_DATA = kptestplugin.rc +rcdir = $(kde_datadir)/kptestplugin + +kpartrc_DATA = testpartui.rc +kpartrcdir = $(kde_datadir)/testpart diff --git a/kontact/plugins/test/kptestplugin.desktop b/kontact/plugins/test/kptestplugin.desktop new file mode 100644 index 000000000..17a3e52e9 --- /dev/null +++ b/kontact/plugins/test/kptestplugin.desktop @@ -0,0 +1,113 @@ +[Desktop Entry] +Type=Service +Icon=konsole +ServiceTypes=Kontact/Plugin,KPluginInfo + +X-KDE-Library=libkptestplugin +X-KDE-KontactPluginVersion=6 + +X-KDE-PluginInfo-Name=kptestplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-EnabledByDefault=false + +Comment=Kontact Test Plugin +Comment[af]=Kontact toets inprop module +Comment[be]=Тэставае дапаўненне Кантакту +Comment[bg]=Приставка за проба +Comment[bs]=Kontact testni dodatak +Comment[ca]=Endollable de prova per a Kontact +Comment[cy]=Ategyn Prawf Kontact +Comment[da]=Kontact Test-plugin +Comment[de]=Test-Modul für Kontact +Comment[el]=Δοκιμαστικό πρόσθετο του Kontact +Comment[eo]=Kontact-Testkromaĵo +Comment[es]=Plugin de prueba para Kontact +Comment[et]=Kontacti testplugin +Comment[eu]=Kontact-en proba plugin-a +Comment[fa]=وصلۀ آزمون Kontact +Comment[fi]=Kontactin testiliitännäinen +Comment[fr]=Module de test pour Kontact +Comment[fy]=Kontact Test-plugin +Comment[gl]=Extensión de Proba para Kontact +Comment[he]=תוסף ניסיון עבור Kontact +Comment[hi]=कॉन्टेक्ट जांच प्लगइन +Comment[hu]=Kontact tesztmodul +Comment[is]=Kontact prufu íforrit +Comment[it]=Plugin test Kontact +Comment[ja]=Kontact テストプラグイン +Comment[ka]=Kontact სატესტო მოდული +Comment[kk]=Сынақ модулі +Comment[km]=កម្មវិធីជំនួយការសាកល្បងក្នុង Kontact +Comment[lt]=Kontact bandymo priedas +Comment[mk]=Приклучок за тест на Контакт +Comment[ms]=Plugin Ujian Kontact +Comment[nb]=Kontact test-programtillegg +Comment[nds]=Test-Moduul för Kontact +Comment[ne]=परीक्षण प्लगइनमा सम्पर्क गर्नुहोस् +Comment[nl]=Kontact Test-plugin +Comment[nn]=Kontact, test-programtillegg +Comment[pl]=Wtyczka Kontact do testowania +Comment[pt]='Plugin' de Teste do Kontact +Comment[pt_BR]=Plug-in para Teste do Kontact +Comment[ro]=Modul de test Kontact +Comment[ru]=Проверочный модуль Kontact +Comment[se]=Kontact, geahččalanlassemoduvla +Comment[sl]=Preizkusni vstavek za Kontact +Comment[sr]=Пробни прикључак Kontact-а +Comment[sr@Latn]=Probni priključak Kontact-a +Comment[sv]=Kontact-testinsticksprogram +Comment[ta]=பரிசோதனை சொருகுப்பொருளை தொடர்பு கொள் +Comment[tg]=Модули матнии Kontact +Comment[tr]=Kontact Test Eklentisi +Comment[uk]=Тестовий втулок Kontact +Comment[uz]=Kontact uchun sinash plagini +Comment[uz@cyrillic]=Kontact учун синаш плагини +Comment[zh_CN]=Kontact Test 插件 +Comment[zh_TW]=Kontact 測試外掛程式 +Name=TestPlugin +Name[af]=Toets inprop module +Name[be]=Тэставае дапаўненне +Name[bg]=Приставка за тестване +Name[ca]=Endollable de prova +Name[cy]=AtegynPrawf +Name[de]=TestModul +Name[el]=Πρόσθετο ελέγχου +Name[eo]=Testo-kromaĵo +Name[fa]=وصلۀ آزمون +Name[fr]=Module de test +Name[fy]=Test-plugin +Name[he]=תוסף ניסיון +Name[hi]=टेस्ट-प्लगइन +Name[hr]=Probni dodatak +Name[hu]=Tesztmodul +Name[is]=Prufu íforrit +Name[it]=Plugin Test +Name[ja]=テストプラグイン +Name[ka]=სატესტო მოდული +Name[kk]=Сынақ модулі +Name[km]=កម្មវិធីជំនួយការសាកល្បង +Name[mk]=Приклучок за тест +Name[ms]=Plugin Ujian +Name[nb]=Test-programtillegg +Name[nds]=Testmoduul +Name[ne]=परीक्षण प्लगइन +Name[nl]=Test-plugin +Name[nn]=Test-programtillegg +Name[nso]=Plugin ya Teko +Name[pl]=Wtyczka testowa +Name[pt_BR]=Plug-in de Teste +Name[ro]=Modul de test +Name[ru]=Проверочный модуль +Name[se]=Geahččalan-lassemoduvla +Name[sk]=TestModul +Name[sl]=Preizkusni vstavek +Name[sr]=Пробни прикључак +Name[sr@Latn]=Probni priključak +Name[sv]=Testinsticksprogram +Name[ta]=சோதனை சொருகுப்பொருள் +Name[tg]=Модули матнӣ +Name[tr]=Test Eklentisi +Name[uk]=Тестовий втулок +Name[ven]=Lingani Plugin +Name[zh_CN]=Test 插件 +Name[zh_TW]=測試外掛程式 diff --git a/kontact/plugins/test/kptestplugin.rc b/kontact/plugins/test/kptestplugin.rc new file mode 100644 index 000000000..0931d6c90 --- /dev/null +++ b/kontact/plugins/test/kptestplugin.rc @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="kptestplugin" version="1"> +<MenuBar> + <Menu name="edit"><Text>&Edit</Text> + <Action name="edit_test"/> + </Menu> +</MenuBar> +</gui> + diff --git a/kontact/plugins/test/test_part.cpp b/kontact/plugins/test/test_part.cpp new file mode 100644 index 000000000..6477d1420 --- /dev/null +++ b/kontact/plugins/test/test_part.cpp @@ -0,0 +1,117 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include "test_part.h" +#include "kaddressbookiface_stub.h" + +#include <qtextedit.h> +#include <qcombobox.h> + +#include "sidebarextension.h" + +#include <kmessagebox.h> +#include <klocale.h> +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <dcopclient.h> +#include <kdcopservicestarter.h> +#include <ktrader.h> +#include <kservice.h> + + +TestPart::TestPart(QObject *parent, const char *name) // ## parentWidget + : KParts::ReadOnlyPart(parent, name) +{ + setInstance( new KInstance("testpart") ); // ## memleak + m_edit = new QTextEdit; + setWidget(m_edit); + setXMLFile("testpartui.rc"); + new KAction( "new contact (test)", 0, this, SLOT( newContact() ), actionCollection(), "test_deleteevent" ); + m_kab_stub = 0L; + + new KParts::SideBarExtension(new QComboBox(this), this, "sbe"); + + kapp->dcopClient()->setNotifications( true ); + connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString&)), + this, SLOT( unregisteredFromDCOP( const QCString& )) ); +} + +TestPart::~TestPart() +{ + kapp->dcopClient()->setNotifications( false ); + delete m_kab_stub; +} + +void TestPart::newContact() +{ + if ( !connectToAddressBook() ) + return; + + kdDebug(5602) << "Calling newContact" << endl; + m_kab_stub->newContact(); + + // If critical call: test that it worked ok + if ( !m_kab_stub->ok() ) { + kdDebug(5602) << "Communication problem - ERROR" << endl; + // TODO handle the error + } +} + +bool TestPart::connectToAddressBook() +{ + if ( !m_kab_stub ) + { + QString error; + QCString dcopService; + int result = KDCOPServiceStarter::self()->findServiceFor( "DCOP/AddressBook", QString::null, QString::null, &error, &dcopService ); + if ( result != 0 ) { + // You might want to show "error" (if not empty) here, using e.g. KMessageBox + return false; + } + // TODO document the required named for the dcop interfaces e.g. "CalendarIface". + QCString dcopObjectId = "KAddressBookIface"; + m_kab_stub = new KAddressBookIface_stub(kapp->dcopClient(), dcopService, dcopObjectId); + } + return m_kab_stub != 0L; +} + +void TestPart::unregisteredFromDCOP( const QCString& appId ) +{ + if ( m_kab_stub && m_kab_stub->app() == appId ) + { + // Delete the stub so that the next time we need the addressbook, + // we'll know that we need to start a new one. + delete m_kab_stub; + m_kab_stub = 0L; + } +} + +bool TestPart::openFile() +{ + m_edit->setText(m_file); + return true; +} + +#include "test_part.moc" diff --git a/kontact/plugins/test/test_part.h b/kontact/plugins/test/test_part.h new file mode 100644 index 000000000..8f2a927c1 --- /dev/null +++ b/kontact/plugins/test/test_part.h @@ -0,0 +1,61 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef TEST_PART_H +#define TEST_PART_H + + + +#include <kparts/part.h> + +class QTextEdit; +class KAddressBookIface_stub; + +class TestPart : public KParts::ReadOnlyPart +{ + Q_OBJECT + +public: + + TestPart(QObject *parent=0, const char *name=0); + ~TestPart(); + +protected: + + virtual bool openFile(); + bool connectToAddressBook(); + +protected slots: + + void newContact(); + void unregisteredFromDCOP( const QCString& ); + +private: + + QTextEdit *m_edit; + KAddressBookIface_stub *m_kab_stub; + +}; + + +#endif diff --git a/kontact/plugins/test/test_plugin.cpp b/kontact/plugins/test/test_plugin.cpp new file mode 100644 index 000000000..62bd74bd2 --- /dev/null +++ b/kontact/plugins/test/test_plugin.cpp @@ -0,0 +1,61 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#include <kmessagebox.h> +#include <kaction.h> +#include <kgenericfactory.h> +#include <kstatusbar.h> + +#include "core.h" + +#include "test_plugin.h" +#include "test_part.h" + +typedef KGenericFactory< TestPlugin, Kontact::Core > TestPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkptestplugin, TestPluginFactory( "kptestplugin" ) ) + +TestPlugin::TestPlugin(Kontact::Core *_core, const char *name, const QStringList &) + : Kontact::Plugin(_core, _core, name) +{ + setInstance(TestPluginFactory::instance()); + + insertNewAction(new KAction("Test", 0, this, SLOT(slotTestMenu()), actionCollection(), "edit_test")); + + setXMLFile("kptestplugin.rc"); +} + +TestPlugin::~TestPlugin() +{ +} + +void TestPlugin::slotTestMenu() +{ + core()->statusBar()->message("Test menu activated"); +} + +KParts::Part* TestPlugin::createPart() +{ + return new TestPart(this, "testpart"); +} + +#include "test_plugin.moc" diff --git a/kontact/plugins/test/test_plugin.h b/kontact/plugins/test/test_plugin.h new file mode 100644 index 000000000..35b60283d --- /dev/null +++ b/kontact/plugins/test/test_plugin.h @@ -0,0 +1,51 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef TEST_PLUGIN_H +#define TEST_PLUGIN_H + + +#include "plugin.h" + + +class TestPart; + + +class TestPlugin : public Kontact::Plugin +{ + Q_OBJECT + +public: + + TestPlugin(Kontact::Core *core, const char *name, const QStringList &); + ~TestPlugin(); + +protected: + KParts::Part* createPart(); + +private slots: + + void slotTestMenu(); +}; + +#endif diff --git a/kontact/plugins/test/testpartui.rc b/kontact/plugins/test/testpartui.rc new file mode 100644 index 000000000..ad5c6764d --- /dev/null +++ b/kontact/plugins/test/testpartui.rc @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!DOCTYPE gui> +<gui name="testpart" version="1"> +<MenuBar> + <Menu name="edit"><Text>&Edit</Text> + <Action name="test_deleteevent"/> + </Menu> +</MenuBar> +</gui> + diff --git a/kontact/plugins/weather/Makefile.am b/kontact/plugins/weather/Makefile.am new file mode 100644 index 000000000..dc547a0ce --- /dev/null +++ b/kontact/plugins/weather/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir)/libkdepim -I$(top_srcdir) $(all_includes) + +kde_module_LTLIBRARIES = libkontact_weatherplugin.la +libkontact_weatherplugin_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkontact_weatherplugin_la_LIBADD = $(top_builddir)/kontact/interfaces/libkpinterfaces.la $(LIB_KPARTS) $(top_builddir)/libkdepim/libkdepim.la + +libkontact_weatherplugin_la_SOURCES = weather_plugin.cpp summarywidget.cpp \ + summarywidget.skel + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir)/kontact +service_DATA = weatherplugin.desktop diff --git a/kontact/plugins/weather/summarywidget.cpp b/kontact/plugins/weather/summarywidget.cpp new file mode 100644 index 000000000..04a559ae4 --- /dev/null +++ b/kontact/plugins/weather/summarywidget.cpp @@ -0,0 +1,230 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#include <qimage.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> + +#include <dcopclient.h> +#include <dcopref.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kprocess.h> +#include <kurllabel.h> + +#include "summarywidget.h" + +SummaryWidget::SummaryWidget( QWidget *parent, const char *name ) + : Kontact::Summary( parent, name ), + DCOPObject( "WeatherSummaryWidget" ), mProc( 0 ) +{ + mLayout = new QVBoxLayout( this, 3, 3 ); + mLayout->setAlignment( Qt::AlignTop ); + + QPixmap icon = KGlobal::iconLoader()->loadIcon( "kweather", KIcon::Desktop, KIcon::SizeMedium ); + QWidget *header = createHeader( this, icon, i18n( "Weather Service" ) ); + mLayout->addWidget( header ); + + QString error; + QCString appID; + bool serviceAvailable = true; + if ( !kapp->dcopClient()->isApplicationRegistered( "KWeatherService" ) ) { + if ( KApplication::startServiceByDesktopName( "kweatherservice", QStringList(), &error, &appID ) ) { + QLabel *label = new QLabel( i18n( "No weather dcop service available;\nyou need KWeather to use this plugin." ), this ); + mLayout->addWidget( label, Qt::AlignHCenter | AlignVCenter ); + serviceAvailable = false; + } + } + + if ( serviceAvailable ) { + connectDCOPSignal( 0, 0, "fileUpdate(QString)", "refresh(QString)", false ); + connectDCOPSignal( 0, 0, "stationRemoved(QString)", "stationRemoved(QString)", false ); + + DCOPRef dcopCall( "KWeatherService", "WeatherService" ); + DCOPReply reply = dcopCall.call( "listStations()", true ); + if ( reply.isValid() ) { + mStations = reply; + + connect( &mTimer, SIGNAL( timeout() ), this, SLOT( timeout() ) ); + mTimer.start( 0 ); + } else { + kdDebug(5602) << "ERROR: dcop reply not valid..." << endl; + } + } +} + + +void SummaryWidget::updateView() +{ + mLayouts.setAutoDelete( true ); + mLayouts.clear(); + mLayouts.setAutoDelete( false ); + + mLabels.setAutoDelete( true ); + mLabels.clear(); + mLabels.setAutoDelete( false ); + + if ( mStations.count() == 0 ) { + kdDebug(5602) << "No weather stations defined..." << endl; + return; + } + + + QValueList<WeatherData> dataList = mWeatherMap.values(); + qHeapSort( dataList ); + + QValueList<WeatherData>::Iterator it; + for ( it = dataList.begin(); it != dataList.end(); ++it ) { + QString cover; + for ( uint i = 0; i < (*it).cover().count(); ++i ) + cover += QString( "- %1\n" ).arg( (*it).cover()[ i ] ); + + QImage img; + img = (*it).icon(); + + QGridLayout *layout = new QGridLayout( mLayout, 3, 3, 3 ); + mLayouts.append( layout ); + + KURLLabel* urlLabel = new KURLLabel( this ); + urlLabel->installEventFilter( this ); + urlLabel->setURL( (*it).stationID() ); + urlLabel->setPixmap( img.smoothScale( 32, 32 ) ); + urlLabel->setMaximumSize( urlLabel->sizeHint() ); + urlLabel->setAlignment( AlignTop ); + layout->addMultiCellWidget( urlLabel, 0, 1, 0, 0 ); + mLabels.append( urlLabel ); + connect ( urlLabel, SIGNAL( leftClickedURL( const QString& ) ), + this, SLOT( showReport( const QString& ) ) ); + + QLabel* label = new QLabel( this ); + label->setText( QString( "%1 (%2)" ).arg( (*it).name() ).arg( (*it).temperature() ) ); + QFont font = label->font(); + font.setBold( true ); + label->setFont( font ); + label->setAlignment( AlignLeft ); + layout->addMultiCellWidget( label, 0, 0, 1, 2 ); + mLabels.append( label ); + + QString labelText; + labelText = QString( "<b>%1:</b> %2<br>" + "<b>%3:</b> %4<br>" + "<b>%5:</b> %6" ) + .arg( i18n( "Last updated on" ) ) + .arg( (*it).date() ) + .arg( i18n( "Wind Speed" ) ) + .arg( (*it).windSpeed() ) + .arg( i18n( "Rel. Humidity" ) ) + .arg( (*it).relativeHumidity() ); + + QToolTip::add( label, labelText.replace( " ", " " ) ); + + label = new QLabel( cover, this ); + label->setAlignment( AlignLeft ); + layout->addMultiCellWidget( label, 1, 1, 1, 2 ); + mLabels.append( label ); + } + + for ( QLabel *label = mLabels.first(); label; label = mLabels.next() ) + label->show(); +} + +void SummaryWidget::timeout() +{ + mTimer.stop(); + + DCOPRef dcopCall( "KWeatherService", "WeatherService" ); + dcopCall.send( "updateAll()" ); + + mTimer.start( 15 * 60000 ); +} + +void SummaryWidget::refresh( QString station ) +{ + DCOPRef dcopCall( "KWeatherService", "WeatherService" ); + + mWeatherMap[ station ].setIcon( dcopCall.call( "currentIcon(QString)", station, true ) ); + mWeatherMap[ station ].setName( dcopCall.call( "stationName(QString)", station, true ) ); + mWeatherMap[ station ].setCover( dcopCall.call( "cover(QString)", station, true ) ); + mWeatherMap[ station ].setDate( dcopCall.call( "date(QString)", station, true ) ); + mWeatherMap[ station ].setTemperature( dcopCall.call( "temperature(QString)", station, true ) ); + mWeatherMap[ station ].setWindSpeed( dcopCall.call( "wind(QString)", station, true ) ); + mWeatherMap[ station ].setRelativeHumidity( dcopCall.call( "relativeHumidity(QString)", station, true ) ); + mWeatherMap[ station ].setStationID(station); + + updateView(); +} + +void SummaryWidget::stationRemoved( QString station ) +{ + mWeatherMap.remove( station ); + updateView(); +} + +bool SummaryWidget::eventFilter( QObject *obj, QEvent* e ) +{ + if ( obj->inherits( "KURLLabel" ) ) { + if ( e->type() == QEvent::Enter ) + emit message( + i18n( "View Weather Report for Station" ) ); + if ( e->type() == QEvent::Leave ) + emit message( QString::null ); + } + + return Kontact::Summary::eventFilter( obj, e ); +} + +QStringList SummaryWidget::configModules() const +{ + return QStringList( "kcmweatherservice.desktop" ); +} + +void SummaryWidget::updateSummary( bool ) +{ + timeout(); +} + +void SummaryWidget::showReport( const QString &stationID ) +{ + mProc = new KProcess; + QApplication::connect( mProc, SIGNAL( processExited( KProcess* ) ), + this, SLOT( reportFinished( KProcess* ) ) ); + *mProc << "kweatherreport"; + *mProc << stationID; + + if ( !mProc->start() ) { + delete mProc; + mProc = 0; + } +} + +void SummaryWidget::reportFinished( KProcess* ) +{ + mProc->deleteLater(); + mProc = 0; +} + +#include "summarywidget.moc" diff --git a/kontact/plugins/weather/summarywidget.h b/kontact/plugins/weather/summarywidget.h new file mode 100644 index 000000000..40e0bb705 --- /dev/null +++ b/kontact/plugins/weather/summarywidget.h @@ -0,0 +1,123 @@ +/* + This file is part of Kontact. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef SUMMARYWIDGET_H +#define SUMMARYWIDGET_H + +#include "summary.h" + +#include <dcopobject.h> + +#include <qmap.h> +#include <qpixmap.h> +#include <qptrlist.h> +#include <qstringlist.h> +#include <qtimer.h> +#include <qwidget.h> + +class KProcess; + +class QGridLayout; +class QLabel; +class QVBoxLayout; + +class WeatherData +{ + public: + void setIcon( const QPixmap &icon ) { mIcon = icon; } + QPixmap icon() const { return mIcon; } + + void setName( const QString &name ) { mName = name; } + QString name() const { return mName; } + + void setCover( const QStringList& cover ) { mCover = cover; } + QStringList cover() const { return mCover; } + + void setDate( const QString &date ) { mDate = date; } + QString date() const { return mDate; } + + void setTemperature( const QString &temperature ) { mTemperature = temperature; } + QString temperature() const { return mTemperature; } + + void setWindSpeed( const QString &windSpeed ) { mWindSpeed = windSpeed; } + QString windSpeed() const { return mWindSpeed; } + + void setRelativeHumidity( const QString &relativeHumidity ) { mRelativeHumidity = relativeHumidity; } + QString relativeHumidity() const { return mRelativeHumidity; } + + void setStationID( const QString &station ) { mStationID = station;} + QString stationID() { return mStationID; } + + bool operator< ( const WeatherData &data ) + { + return ( QString::localeAwareCompare( mName, data.mName ) < 0 ); + } + + private: + QPixmap mIcon; + QString mName; + QStringList mCover; + QString mDate; + QString mTemperature; + QString mWindSpeed; + QString mRelativeHumidity; + QString mStationID; +}; + +class SummaryWidget : public Kontact::Summary, public DCOPObject +{ + Q_OBJECT + K_DCOP + public: + SummaryWidget( QWidget *parent, const char *name = 0 ); + + QStringList configModules() const; + + void updateSummary( bool force = false ); + + k_dcop: + virtual void refresh( QString ); + virtual void stationRemoved( QString ); + + protected: + virtual bool eventFilter( QObject *obj, QEvent *e ); + + private slots: + void updateView(); + void timeout(); + void showReport( const QString& ); + void reportFinished( KProcess* ); + + private: + QStringList mStations; + QMap<QString, WeatherData> mWeatherMap; + QTimer mTimer; + + QPtrList<QLabel> mLabels; + QPtrList<QGridLayout> mLayouts; + QVBoxLayout *mLayout; + + KProcess* mProc; +}; + +#endif diff --git a/kontact/plugins/weather/weather_plugin.cpp b/kontact/plugins/weather/weather_plugin.cpp new file mode 100644 index 000000000..4c1a91e6e --- /dev/null +++ b/kontact/plugins/weather/weather_plugin.cpp @@ -0,0 +1,61 @@ +/* + This file is part of Kontact. + Copyright (C) 2003 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <kaboutdata.h> +#include <kgenericfactory.h> +#include <kparts/componentfactory.h> + +#include "core.h" +#include "summarywidget.h" + +#include "weather_plugin.h" + +typedef KGenericFactory< WeatherPlugin, Kontact::Core > WeatherPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libkontact_weatherplugin, + WeatherPluginFactory( "kontact_weatherplugin" ) ) + +WeatherPlugin::WeatherPlugin( Kontact::Core *core, const char *name, const QStringList& ) + : Kontact::Plugin( core, core, name ), mAboutData( 0 ) +{ + setInstance( WeatherPluginFactory::instance() ); +} + +Kontact::Summary *WeatherPlugin::createSummaryWidget( QWidget *parentWidget ) +{ + return new SummaryWidget( parentWidget ); +} + +const KAboutData *WeatherPlugin::aboutData() +{ + if ( !mAboutData ) { + mAboutData = new KAboutData( "weatherplugin", I18N_NOOP( "Weather Information" ), + "0.1", + I18N_NOOP( "Weather Information" ), + KAboutData::License_GPL_V2, + "(c) 2003 The Kontact developers" ); + mAboutData->addAuthor( "Ian Reinhart Geiser", "", "geiseri@kde.org" ); + mAboutData->addAuthor( "Tobias Koenig", "", "tokoe@kde.org" ); + mAboutData->addCredit( "John Ratke", + I18N_NOOP( "Improvements and more code cleanups" ), + "jratke@comcast.net" ); + } + + return mAboutData; +} diff --git a/kontact/plugins/weather/weather_plugin.h b/kontact/plugins/weather/weather_plugin.h new file mode 100644 index 000000000..637ebea9c --- /dev/null +++ b/kontact/plugins/weather/weather_plugin.h @@ -0,0 +1,44 @@ +/* + This file is part of Kontact. + Copyright (C) 2003 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WEATHER_PLUGIN_H +#define WEATHER_PLUGIN_H + +#include "plugin.h" + +class SummaryWidget; + +class WeatherPlugin : public Kontact::Plugin +{ + public: + WeatherPlugin( Kontact::Core *core, const char *name, const QStringList& ); + WeatherPlugin(); + + virtual Kontact::Summary *createSummaryWidget( QWidget *parentWidget ); + + const KAboutData *aboutData(); + + protected: + virtual KParts::ReadOnlyPart *createPart() { return 0; } + private: + KAboutData *mAboutData; +}; + +#endif diff --git a/kontact/plugins/weather/weatherplugin.desktop b/kontact/plugins/weather/weatherplugin.desktop new file mode 100644 index 000000000..68c1924e3 --- /dev/null +++ b/kontact/plugins/weather/weatherplugin.desktop @@ -0,0 +1,92 @@ +[Desktop Entry] +Type=Service +Icon=kweather +ServiceTypes=Kontact/Plugin,KPluginInfo +TryExec=kweatherservice + +X-KDE-Library=libkontact_weatherplugin +X-KDE-KontactIdentifier=weather +X-KDE-KontactPluginVersion=6 +X-KDE-KontactPluginHasSummary=true +X-KDE-KontactPluginHasPart=false + +X-KDE-PluginInfo-Name=kontact_weatherplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-EnabledByDefault=true + +Comment=Kontact Weather Component +Comment[bg]=Приставка за метеорологичното време +Comment[ca]=Component del temps del Kontact +Comment[da]=Vejrkomponent til Kontact +Comment[de]=Wetter-Komponente für Kontact +Comment[el]=Συστατικό καιρού του Kontact +Comment[es]=Extensión de meteorología para Kontact +Comment[et]=Kontacti ilmaplugin +Comment[fr]=Composant météo pour Kontact +Comment[is]=Kontact veðurfréttaeining +Comment[it]=Componente meteorologico di Kontact +Comment[ja]=Kontact 気象情報コンポーネント +Comment[km]=សមាសភាគអាកាសធាតុ Kontact +Comment[nds]=Kontact-Wederkomponent +Comment[nl]=Kontact Weercomponent +Comment[pl]=Składnik Kontaktu wiadomości o pogodzie +Comment[ru]=Компонент информации о погоде для Kontact +Comment[sr]=Компонента времена за Kontact +Comment[sr@Latn]=Komponenta vremena za Kontact +Comment[sv]=Kontacts väderkomponent +Comment[tr]=Kontact Hava Durumu Bileşeni +Comment[zh_CN]=Kontact 天气插件 +Comment[zh_TW]=Kontact 天氣組件 +Name=Weather Service +Name[af]=Weer diens +Name[ar]=خدمة الطقس +Name[bg]=Информация за времето +Name[br]=Servij an amzer +Name[ca]=Servei meteorològic +Name[cs]=Služba počasí +Name[cy]=GwasanaethTywydd +Name[da]=Vejrtjeneste +Name[de]=Wetterdienst +Name[el]=Υπηρεσία πρόβλεψης Καιρού +Name[eo]=Veterservo +Name[es]=Servicio meteorológico +Name[et]=Ilmateade +Name[eu]=Eguraldiaren zerbitzua +Name[fa]=خدمت آب و هوا +Name[fi]=Sääpalvelu +Name[fr]=KWeatherService +Name[fy]=Waarberjocht +Name[ga]=Seirbhís Aimsire +Name[gl]=Servicio do Tempo +Name[he]=שירות מזג אוויר +Name[hu]=Időjárás +Name[is]=Veðurþjónusta +Name[it]=Servizio meteorologico +Name[ja]=気象サービス +Name[ka]=ამინდის მომსახურება +Name[kk]=Ауа райы қызметі +Name[km]=សេវាអាកាសធាតុ +Name[lt]=Orų tarnyba +Name[mk]=Временска прогноза +Name[nb]=Værtjeneste +Name[nds]=Wederdeenst +Name[ne]=मौसम कार्य +Name[nl]=Weerbericht +Name[nn]=Vêrmelding +Name[pl]=Pogoda +Name[pt]=Serviço Meteorológico +Name[pt_BR]=Serviço de Previsão do Tempo +Name[ru]=Погода +Name[sk]=Služba počasie +Name[sl]=Vremenska storitev +Name[sr]=Време +Name[sr@Latn]=Vreme +Name[sv]=Väderleksprognos +Name[th]=รายงานอากาศ +Name[tr]=Hava Durumu Servisi +Name[uk]=Служба погоди +Name[uz]=Ob-havo xizmati +Name[uz@cyrillic]=Об-ҳаво хизмати +Name[zh_CN]=天气服务 +Name[zh_TW]=天氣服務 diff --git a/kontact/profiles/KontactDefaults/Makefile.am b/kontact/profiles/KontactDefaults/Makefile.am new file mode 100644 index 000000000..333084e92 --- /dev/null +++ b/kontact/profiles/KontactDefaults/Makefile.am @@ -0,0 +1,6 @@ +profile_DATA = \ + profile.cfg \ + kontactrc \ + korganizerrc + +profiledir = $(kde_datadir)/kontact/profiles/KontactDefaults diff --git a/kontact/profiles/KontactDefaults/kontactrc b/kontact/profiles/KontactDefaults/kontactrc new file mode 100644 index 000000000..9a33d0c08 --- /dev/null +++ b/kontact/profiles/KontactDefaults/kontactrc @@ -0,0 +1,35 @@ +[General] +activeBackground=KONTACT_PROFILE_DELETE_KEY +activeBlend=KONTACT_PROFILE_DELETE_KEY +activeForeground=KONTACT_PROFILE_DELETE_KEY +activeTitleBtnBg=KONTACT_PROFILE_DELETE_KEY +alternateBackground=KONTACT_PROFILE_DELETE_KEY +background=KONTACT_PROFILE_DELETE_KEY +buttonBackground=KONTACT_PROFILE_DELETE_KEY +buttonForeground=KONTACT_PROFILE_DELETE_KEY +contrast=KONTACT_PROFILE_DELETE_KEY +foreground=KONTACT_PROFILE_DELETE_KEY +frame=KONTACT_PROFILE_DELETE_KEY +handle=KONTACT_PROFILE_DELETE_KEY +inactiveBackground=KONTACT_PROFILE_DELETE_KEY +inactiveBlend=KONTACT_PROFILE_DELETE_KEY +inactiveForeground=KONTACT_PROFILE_DELETE_KEY +inactiveFrame=KONTACT_PROFILE_DELETE_KEY +inactiveHandle=KONTACT_PROFILE_DELETE_KEY +inactiveTitleBtnBg=KONTACT_PROFILE_DELETE_KEY +linkColor=KONTACT_PROFILE_DELETE_KEY +selectBackground=KONTACT_PROFILE_DELETE_KEY +selectForeground=KONTACT_PROFILE_DELETE_KEY +shadeSortColumn=KONTACT_PROFILE_DELETE_KEY +visitedLinkColor=KONTACT_PROFILE_DELETE_KEY +windowBackground=KONTACT_PROFILE_DELETE_KEY +windowForeground=KONTACT_PROFILE_DELETE_KEY + +[MainWindow Toolbar navigatorToolBar] +Hidden=true + +[View] +SidePaneSplitter=115,1088 + +[Icons] +Theme=KONTACT_PROFILE_DELETE_KEY diff --git a/kontact/profiles/KontactDefaults/korganizerrc b/kontact/profiles/KontactDefaults/korganizerrc new file mode 100644 index 000000000..d928c44ff --- /dev/null +++ b/kontact/profiles/KontactDefaults/korganizerrc @@ -0,0 +1,3 @@ +[Views] +Agenda View Calendar Display=CalendarsMerged + diff --git a/kontact/profiles/KontactDefaults/profile.cfg b/kontact/profiles/KontactDefaults/profile.cfg new file mode 100644 index 000000000..8e35c22d9 --- /dev/null +++ b/kontact/profiles/KontactDefaults/profile.cfg @@ -0,0 +1,4 @@ +[Kontact Profile] +Description=Default KDE Kontact settings +Identifier=KontactDefaults +Name=Kontact Style diff --git a/kontact/profiles/Makefile.am b/kontact/profiles/Makefile.am new file mode 100644 index 000000000..bb680cdba --- /dev/null +++ b/kontact/profiles/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = KontactDefaults OutlookDefaults diff --git a/kontact/profiles/OutlookDefaults/Makefile.am b/kontact/profiles/OutlookDefaults/Makefile.am new file mode 100644 index 000000000..87e8814d6 --- /dev/null +++ b/kontact/profiles/OutlookDefaults/Makefile.am @@ -0,0 +1,6 @@ +profile_DATA = \ + profile.cfg \ + kontactrc \ + korganizerrc + +profiledir = $(kde_datadir)/kontact/profiles/OutlookDefaults diff --git a/kontact/profiles/OutlookDefaults/kontactrc b/kontact/profiles/OutlookDefaults/kontactrc new file mode 100644 index 000000000..f086bedf1 --- /dev/null +++ b/kontact/profiles/OutlookDefaults/kontactrc @@ -0,0 +1,33 @@ +[General] +activeBackground=47,103,255 +activeBlend=41,93,180 +activeForeground=255,255,255 +activeTitleBtnBg=220,220,220 +alternateBackground=240,240,240 +background=238,238,230 +buttonBackground=238,234,222 +buttonForeground=0,0,0 +contrast=7 +foreground=0,0,0 +frame=238,238,230 +handle=238,238,230 +inactiveBackground=220,220,220 +inactiveBlend=220,220,220 +inactiveForeground=0,0,0 +inactiveFrame=238,238,230 +inactiveHandle=238,238,230 +inactiveTitleBtnBg=220,220,220 +linkColor=0,0,192 +selectBackground=74,121,205 +selectForeground=255,255,255 +shadeSortColumn=true +visitedLinkColor=128,0,128 +windowBackground=255,255,255 +windowForeground=0,0,0 +[Icons] +Theme=Locolor + +[MainWindow Toolbar navigatorToolBar] +Hidden=false + + diff --git a/kontact/profiles/OutlookDefaults/korganizerrc b/kontact/profiles/OutlookDefaults/korganizerrc new file mode 100644 index 000000000..e0c1178bb --- /dev/null +++ b/kontact/profiles/OutlookDefaults/korganizerrc @@ -0,0 +1,3 @@ +[Views] +Agenda View Calendar Display=CalendarsSideBySide + diff --git a/kontact/profiles/OutlookDefaults/profile.cfg b/kontact/profiles/OutlookDefaults/profile.cfg new file mode 100644 index 000000000..0fef517e1 --- /dev/null +++ b/kontact/profiles/OutlookDefaults/profile.cfg @@ -0,0 +1,4 @@ +[Kontact Profile] +Description=Settings resembling MS Outlook +Identifier=OutlookDefaults +Name=Outlook Style diff --git a/kontact/src/Kontact.desktop b/kontact/src/Kontact.desktop new file mode 100644 index 000000000..6cd9d0d3a --- /dev/null +++ b/kontact/src/Kontact.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Name=Kontact +Name[be]=Кантакт +Name[hi]=कॉन्टेक्ट +Name[mk]=Контакт +Name[ne]=सम्पर्क गर्नुहोस् +Name[sv]=Kontakt +Name[ta]=தொடர்பு கொள் +Name[zh_TW]=Kontact 個人資訊管理 +Exec=kontact +Type=Application +Icon=kontact +GenericName=Personal Information Manager +GenericName[af]=Personlike informasie bestuurder +GenericName[ar]=منظم المعلومات الشخصي +GenericName[be]=Кіраванне пэрсанальнай інфармацыяй +GenericName[bg]=Лична информация +GenericName[bs]=Upravitelj ličnim informacijama +GenericName[ca]=Gestor d'informació personal +GenericName[cs]=Správce osobních informací +GenericName[cy]=Rheolydd Gwybodaeth Personol +GenericName[da]=Personlig informationshåndtering +GenericName[de]=Persönlicher Informationsmanager +GenericName[el]=Προσωπικός διαχειριστής πληροφοριών +GenericName[eo]=Persona Inform-Mastrumilo +GenericName[es]=Gestor de información personal +GenericName[et]=Personaalse info haldur +GenericName[eu]=Informazio pertsonalaren kudeatzailea +GenericName[fa]=مدیر اطلاعات شخصی +GenericName[fi]=Henkilötietojen hallinta +GenericName[fr]=Gestionnaire d'informations personnelles +GenericName[gl]=Xestor de Información Persoal +GenericName[he]=מנהל מידע אישי +GenericName[hi]=निजी जानकारी प्रबंधक +GenericName[hu]=Információkezelő +GenericName[is]=Persónulegur upplýsingastjórnandi +GenericName[it]=Gestione informazioni personali +GenericName[ja]=個人情報マネージャ +GenericName[ka]=პირადი ინფორმაციის მმართველი +GenericName[kk]=Дербес Ақпарат Менеджері +GenericName[km]=កម្មវិធីគ្រប់គ្រងព័ត៌មានផ្ទាល់ខ្លួន +GenericName[lt]=Asmeninės informacijos tvarkyklė +GenericName[mk]=Менаџер на лични информации +GenericName[ms]=Pengurus Makumat Peribadi +GenericName[nb]=Personlig informasjonsbehandler +GenericName[nds]=Pleger för persöönliche Informatschonen +GenericName[ne]=व्यक्तिगत सूचना प्रबन्धक +GenericName[nn]=Personleg informasjonshandtering +GenericName[pl]=Program do zarządzania informacjami osobistymi +GenericName[pt]=Gestor Pessoal de Informações +GenericName[pt_BR]=Gerenciador de Informações Pessoais +GenericName[ro]=Manager de informaţii personale +GenericName[ru]=Персональный информационный менеджер +GenericName[se]=Persuvnnalaš diehtogieđaheapmi +GenericName[sk]=Osobný manažér informácii +GenericName[sl]=Osebni upravitelj informacij +GenericName[sr]=Менаџер личних информација +GenericName[sr@Latn]=Menadžer ličnih informacija +GenericName[sv]=Personlig informationshantering +GenericName[ta]=அந்தரங்க தகவல் மேலாளர் +GenericName[tg]=Мудири маълумоти шахсӣ +GenericName[tr]=Kişisel Bilgi Yöneticisi +GenericName[uk]=Менеджер особистої інформації +GenericName[uz]=Shaxsiy maʼlumot boshqaruvchisi +GenericName[uz@cyrillic]=Шахсий маълумот бошқарувчиси +GenericName[zh_CN]=个人信息管理器 +GenericName[zh_TW]=個人資訊管理者 +Terminal=false +X-KDE-StartupNotify=true +Categories=Qt;KDE;Office;Network;Email; +DocPath=kontact/index.html diff --git a/kontact/src/Makefile.am b/kontact/src/Makefile.am new file mode 100644 index 000000000..b30c5bc77 --- /dev/null +++ b/kontact/src/Makefile.am @@ -0,0 +1,42 @@ +SUBDIRS = about + +INCLUDES = -I$(top_srcdir)/kontact/interfaces -I$(top_srcdir) $(all_includes) + +lib_LTLIBRARIES = libkontact.la +libkontact_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -version-info 1:0 +libkontact_la_LIBADD = $(LIB_KDECORE) +libkontact_la_SOURCES = prefs.kcfgc + +bin_PROGRAMS = kontact + +kontact_METASOURCES = AUTO +kontact_LDFLAGS = $(all_libraries) $(KDE_RPATH) +kontact_LDADD = $(top_builddir)/libkdepim/libkdepim.la \ + $(top_builddir)/kontact/interfaces/libkpinterfaces.la libkontact.la \ + $(LIB_KPARTS) $(LIB_KUTILS) $(LIB_KHTML) +kontact_SOURCES = main.cpp mainwindow.cpp sidepanebase.cpp \ + iconsidepane.cpp aboutdialog.cpp profilemanager.cpp profiledialog.cpp \ + kontactiface.skel +kontact_COMPILE_FIRST = prefs.h + +kde_module_LTLIBRARIES = kcm_kontact.la + +kcm_kontact_la_SOURCES = kcmkontact.cpp +kcm_kontact_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +kcm_kontact_la_LIBADD = libkontact.la $(top_builddir)/libkdepim/libkdepim.la +kcm_kontact_la_COMPILE_FIRST = prefs.h + + +rcdir = $(kde_datadir)/kontact +rc_DATA = kontactui.rc + +xdg_apps_DATA = Kontact.desktop kontactdcop.desktop + +kde_kcfg_DATA = kontact.kcfg + +kde_services_DATA = kontactconfig.desktop + +kontactsetdlgdir = $(kde_datadir)/kontact +kontactsetdlg_DATA = kontact.setdlg + +KDE_ICON = AUTO diff --git a/kontact/src/about/Makefile.am b/kontact/src/about/Makefile.am new file mode 100644 index 000000000..b2c7b7605 --- /dev/null +++ b/kontact/src/about/Makefile.am @@ -0,0 +1,6 @@ +about_DATA = \ + top-right-kontact.png \ + main.html \ + kontact.css + +aboutdir = $(kde_datadir)/kontact/about diff --git a/kontact/src/about/kontact.css b/kontact/src/about/kontact.css new file mode 100644 index 000000000..18aa0ddcd --- /dev/null +++ b/kontact/src/about/kontact.css @@ -0,0 +1,30 @@ + +#headerR { + position: absolute; + right: 0px; + width: 430px; + height: 131px; + background-image: url(top-right-kontact.png); +} + +#title { + right: 125px; +} + +#tagline { + right: 125px; +} + +#boxCenter { + background-image: url(box-center-kontact.png); + background-repeat: no-repeat; + background-color: #dfe7f3; + background-position: bottom right; +} + +#subtext { + font-style: italic; +} + +/* vim:set sw=2 et nocindent smartindent: */ + diff --git a/kontact/src/about/main.html b/kontact/src/about/main.html new file mode 100644 index 000000000..a36cc2537 --- /dev/null +++ b/kontact/src/about/main.html @@ -0,0 +1,66 @@ +<?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 "kontact.css"; + body {font-size: %1px;} + /*]]>*/ + </style> + + <title>Kontact</title> +</head> + +<body> + <div id="header"> + <div id="headerL"/> + <div id="headerR"/> + + <div id="title"> + %2 <!-- Kontact --> + </div> + + <div id="tagline"> + %3 <!-- Catchphrase --> + </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"> + %4<!-- Kontact is ... --> + </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"> + <!--Welcome to Kontact--> + %5 + </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/kontact/src/about/top-right-kontact.png b/kontact/src/about/top-right-kontact.png Binary files differnew file mode 100644 index 000000000..bf15f38b5 --- /dev/null +++ b/kontact/src/about/top-right-kontact.png diff --git a/kontact/src/aboutdialog.cpp b/kontact/src/aboutdialog.cpp new file mode 100644 index 000000000..d0a43721a --- /dev/null +++ b/kontact/src/aboutdialog.cpp @@ -0,0 +1,177 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include "aboutdialog.h" + +#include "core.h" +#include "plugin.h" + +#include <klocale.h> +#include <kiconloader.h> +#include <kaboutdata.h> +#include <kactivelabel.h> +#include <ktextbrowser.h> + +#include <qlayout.h> +#include <qlabel.h> + +#include <kdebug.h> + +using namespace Kontact; + +AboutDialog::AboutDialog( Kontact::Core *core, const char *name ) + : KDialogBase( IconList, i18n("About Kontact"), Ok, Ok, core, name, false, + true ), + mCore( core ) +{ + addAboutData( i18n( "Kontact Container" ), QString( "kontact" ), + KGlobal::instance()->aboutData() ); + + QValueList<Plugin*> plugins = mCore->pluginList(); + QValueList<Plugin*>::ConstIterator end = plugins.end(); + QValueList<Plugin*>::ConstIterator it = plugins.begin(); + for ( ; it != end; ++it ) + addAboutPlugin( *it ); + + addLicenseText( KGlobal::instance()->aboutData() ); +} + +void AboutDialog::addAboutPlugin( Kontact::Plugin *plugin ) +{ + addAboutData( plugin->title(), plugin->icon(), plugin->aboutData() ); +} + +void AboutDialog::addAboutData( const QString &title, const QString &icon, + const KAboutData *about ) +{ + QPixmap pixmap = KGlobal::iconLoader()->loadIcon( icon, + KIcon::Desktop, 48 ); + + QFrame *topFrame = addPage( title, QString::null, pixmap ); + + QBoxLayout *topLayout = new QVBoxLayout( topFrame ); + + if ( !about ) { + QLabel *label = new QLabel( i18n( "No about information available." ), + topFrame ); + topLayout->addWidget( label ); + } else { + QString text; + + text += "<p><b>" + about->programName() + "</b><br>"; + + text += i18n( "Version %1</p>" ).arg( about->version() ); + + if ( !about->shortDescription().isEmpty() ) { + text += "<p>" + about->shortDescription() + "<br>" + + about->copyrightStatement() + "</p>"; + } + + QString home = about->homepage(); + if ( !home.isEmpty() ) { + text += "<a href=\"" + home + "\">" + home + "</a><br>"; + } + + text.replace( "\n", "<br>" ); + + KActiveLabel *label = new KActiveLabel( text, topFrame ); + label->setAlignment( AlignTop ); + topLayout->addWidget( label ); + + + QTextEdit *personView = new QTextEdit( topFrame ); + personView->setReadOnly( true ); + topLayout->addWidget( personView, 1 ); + + text = ""; + + const QValueList<KAboutPerson> authors = about->authors(); + if ( !authors.isEmpty() ) { + text += i18n( "<p><b>Authors:</b></p>" ); + + QValueList<KAboutPerson>::ConstIterator it; + for ( it = authors.begin(); it != authors.end(); ++it ) { + text += formatPerson( (*it).name(), (*it).emailAddress() ); + if ( !(*it).task().isEmpty() ) + text += "<i>" + (*it).task() + "</i><br>"; + } + } + + const QValueList<KAboutPerson> credits = about->credits(); + if ( !credits.isEmpty() ) { + text += i18n( "<p><b>Thanks to:</b></p>" ); + + QValueList<KAboutPerson>::ConstIterator it; + for ( it = credits.begin(); it != credits.end(); ++it ) { + text += formatPerson( (*it).name(), (*it).emailAddress() ); + if ( !(*it).task().isEmpty() ) + text += "<i>" + (*it).task() + "</i><br>"; + } + } + + const QValueList<KAboutTranslator> translators = about->translators(); + if ( !translators.isEmpty() ) { + text += i18n("<p><b>Translators:</b></p>"); + + QValueList<KAboutTranslator>::ConstIterator it; + for ( it = translators.begin(); it != translators.end(); ++it ) { + text += formatPerson( (*it).name(), (*it).emailAddress() ); + } + } + + personView->setText( text ); + } +} + +QString AboutDialog::formatPerson( const QString &name, const QString &email ) +{ + QString text = name; + if ( !email.isEmpty() ) { + text += " <<a href=\"mailto:" + email + "\">" + email + "</a>>"; + } + + text += "<br>"; + return text; +} + +void AboutDialog::addLicenseText( const KAboutData *about ) +{ + if ( !about || about->license().isEmpty() ) + return; + + QPixmap pixmap = KGlobal::iconLoader()->loadIcon( "signature", + KIcon::Desktop, 48 ); + + QString title = i18n( "%1 License" ).arg( about->programName() ); + + QFrame *topFrame = addPage( title, QString::null, pixmap ); + QBoxLayout *topLayout = new QVBoxLayout( topFrame ); + + KTextBrowser *textBrowser = new KTextBrowser( topFrame ); + textBrowser->setText( QString( "<pre>%1</pre>" ).arg( about->license() ) ); + + topLayout->addWidget( textBrowser ); +} + +#include "aboutdialog.moc" diff --git a/kontact/src/aboutdialog.h b/kontact/src/aboutdialog.h new file mode 100644 index 000000000..9697c5274 --- /dev/null +++ b/kontact/src/aboutdialog.h @@ -0,0 +1,57 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ +#ifndef KONTACT_ABOUTDIALOG_H +#define KONTACT_ABOUTDIALOG_H + +#include <kdialogbase.h> +class KAboutData; +namespace Kontact { + +class Core; +class Plugin; + +class AboutDialog : public KDialogBase +{ + Q_OBJECT + + public: + AboutDialog( Kontact::Core *core, const char *name = 0 ); + + protected: + void addAboutPlugin( Kontact::Plugin *plugin ); + + void addAboutData( const QString &title, const QString &icon, + const KAboutData *about ); + + void addLicenseText( const KAboutData *about ); + + QString formatPerson( const QString &name, const QString &email ); + + private: + Core *mCore; +}; + +} + +#endif diff --git a/kontact/src/hi128-app-kontact.png b/kontact/src/hi128-app-kontact.png Binary files differnew file mode 100644 index 000000000..e8da426c5 --- /dev/null +++ b/kontact/src/hi128-app-kontact.png diff --git a/kontact/src/hi16-app-kontact.png b/kontact/src/hi16-app-kontact.png Binary files differnew file mode 100644 index 000000000..4d6e54d21 --- /dev/null +++ b/kontact/src/hi16-app-kontact.png diff --git a/kontact/src/hi22-app-kontact.png b/kontact/src/hi22-app-kontact.png Binary files differnew file mode 100644 index 000000000..af2614a26 --- /dev/null +++ b/kontact/src/hi22-app-kontact.png diff --git a/kontact/src/hi32-app-kontact.png b/kontact/src/hi32-app-kontact.png Binary files differnew file mode 100644 index 000000000..81d42536f --- /dev/null +++ b/kontact/src/hi32-app-kontact.png diff --git a/kontact/src/hi48-app-kontact.png b/kontact/src/hi48-app-kontact.png Binary files differnew file mode 100644 index 000000000..c45ac6f8d --- /dev/null +++ b/kontact/src/hi48-app-kontact.png diff --git a/kontact/src/hi64-app-kontact.png b/kontact/src/hi64-app-kontact.png Binary files differnew file mode 100644 index 000000000..7d2c409ed --- /dev/null +++ b/kontact/src/hi64-app-kontact.png diff --git a/kontact/src/iconsidepane.cpp b/kontact/src/iconsidepane.cpp new file mode 100644 index 000000000..c7e9c84a0 --- /dev/null +++ b/kontact/src/iconsidepane.cpp @@ -0,0 +1,612 @@ +/* + This file is part of KDE Kontact. + + Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include <qptrlist.h> +#include <qwidgetstack.h> +#include <qsignal.h> +#include <qobjectlist.h> +#include <qlabel.h> +#include <qimage.h> +#include <qpainter.h> +#include <qbitmap.h> +#include <qfontmetrics.h> +#include <qsignalmapper.h> +#include <qstyle.h> +#include <qframe.h> +#include <qdrawutil.h> +#include <qcursor.h> +#include <qtimer.h> +#include <qtooltip.h> + +#include <kpopupmenu.h> +#include <kapplication.h> +#include <kdialog.h> +#include <klocale.h> +#include <kiconloader.h> +#include <sidebarextension.h> + +#include <kdebug.h> + +#include "mainwindow.h" + +#include "plugin.h" + +#include "prefs.h" +#include "iconsidepane.h" + +namespace Kontact +{ + +//ugly wrapper class for adding an operator< to the Plugin class + +class PluginProxy +{ + public: + PluginProxy() + : mPlugin( 0 ) + { } + + PluginProxy( Plugin *plugin ) + : mPlugin( plugin ) + { } + + PluginProxy & operator=( Plugin *plugin ) + { + mPlugin = plugin; + return *this; + } + + bool operator<( PluginProxy &rhs ) const + { + return mPlugin->weight() < rhs.mPlugin->weight(); + } + + Plugin *plugin() const + { + return mPlugin; + } + + private: + Plugin *mPlugin; +}; + +} //namespace + +using namespace Kontact; + +EntryItem::EntryItem( Navigator *parent, Kontact::Plugin *plugin ) + : QListBoxItem( parent ), + mPlugin( plugin ), + mHasHover( false ), + mPaintActive( false ) +{ + reloadPixmap(); + setCustomHighlighting( true ); + setText( plugin->title() ); +} + +EntryItem::~EntryItem() +{ +} + +void EntryItem::reloadPixmap() +{ + int size = (int)navigator()->viewMode(); + if ( size != 0 ) + mPixmap = KGlobal::iconLoader()->loadIcon( mPlugin->icon(), + KIcon::Desktop, size, + mPlugin->disabled() ? + KIcon::DisabledState + : KIcon::DefaultState); + else + mPixmap = QPixmap(); +} + +Navigator* EntryItem::navigator() const +{ + return static_cast<Navigator*>( listBox() ); +} + +int EntryItem::width( const QListBox *listbox ) const +{ + int w = 0; + if( navigator()->showIcons() ) { + w = navigator()->viewMode(); + if ( navigator()->viewMode() == SmallIcons ) + w += 4; + } + if( navigator()->showText() ) { + if ( navigator()->viewMode() == SmallIcons ) + w += listbox->fontMetrics().width( text() ); + else + w = QMAX( w, listbox->fontMetrics().width( text() ) ); + } + return w + ( KDialog::marginHint() * 2 ); +} + +int EntryItem::height( const QListBox *listbox ) const +{ + int h = 0; + if ( navigator()->showIcons() ) + h = (int)navigator()->viewMode() + 4; + if ( navigator()->showText() ) { + if ( navigator()->viewMode() == SmallIcons || !navigator()->showIcons() ) + h = QMAX( h, listbox->fontMetrics().lineSpacing() ) + KDialog::spacingHint() * 2; + else + h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4; + } + return h; +} + +void EntryItem::paint( QPainter *p ) +{ + reloadPixmap(); + + QListBox *box = listBox(); + bool iconAboveText = ( navigator()->viewMode() > SmallIcons ) + && navigator()->showIcons(); + int w = box->viewport()->width(); + int y = iconAboveText ? 2 : + ( ( height( box ) - mPixmap.height() ) / 2 ); + + // draw selected + if ( isCurrent() || isSelected() || mHasHover || mPaintActive ) { + int h = height( box ); + + QBrush brush; + if ( isCurrent() || isSelected() || mPaintActive ) + brush = box->colorGroup().brush( QColorGroup::Highlight ); + else + brush = box->colorGroup().highlight().light( 115 ); + p->fillRect( 1, 0, w - 2, h - 1, brush ); + QPen pen = p->pen(); + QPen oldPen = pen; + pen.setColor( box->colorGroup().mid() ); + p->setPen( pen ); + + p->drawPoint( 1, 0 ); + p->drawPoint( 1, h - 2 ); + p->drawPoint( w - 2, 0 ); + p->drawPoint( w - 2, h - 2 ); + + p->setPen( oldPen ); + } + + if ( !mPixmap.isNull() && navigator()->showIcons() ) { + int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) : + KDialog::marginHint(); + p->drawPixmap( x, y, mPixmap ); + } + + QColor shadowColor = listBox()->colorGroup().background().dark(115); + if ( isCurrent() || isSelected() ) { + p->setPen( box->colorGroup().highlightedText() ); + } + + if ( !text().isEmpty() && navigator()->showText() ) { + QFontMetrics fm = p->fontMetrics(); + + int x = 0; + if ( iconAboveText ) { + x = ( w - fm.width( text() ) ) / 2; + y += fm.height() - fm.descent(); + if ( navigator()->showIcons() ) + y += mPixmap.height(); + } else { + x = KDialog::marginHint() + 4; + if( navigator()->showIcons() ) { + x += mPixmap.width(); + } + + if ( !navigator()->showIcons() || mPixmap.height() < fm.height() ) + y = height( box )/2 - fm.height()/2 + fm.ascent(); + else + y += mPixmap.height()/2 - fm.height()/2 + fm.ascent(); + } + + if ( plugin()->disabled() ) { + p->setPen( box->palette().disabled().text( ) ); + } else if ( isCurrent() || isSelected() || mHasHover ) { + p->setPen( box->colorGroup().highlight().dark(115) ); + p->drawText( x + ( QApplication::reverseLayout() ? -1 : 1), + y + 1, text() ); + p->setPen( box->colorGroup().highlightedText() ); + } + else + p->setPen( box->colorGroup().text() ); + + p->drawText( x, y, text() ); + } + + // ensure that we don't have a stale flag around + if ( isCurrent() || isSelected() ) mHasHover = false; +} + +void EntryItem::setHover( bool hasHover ) +{ + mHasHover = hasHover; +} + +void EntryItem::setPaintActive( bool paintActive ) +{ + mPaintActive = paintActive; +} + +Navigator::Navigator( SidePaneBase *parent, const char *name ) + : KListBox( parent, name ), mSidePane( parent ), + mShowIcons( true ), mShowText( true ) +{ + mMouseOn = 0; + mHighlightItem = 0; + mViewMode = sizeIntToEnum( Prefs::self()->sidePaneIconSize() ); + mShowIcons = Prefs::self()->sidePaneShowIcons(); + mShowText = Prefs::self()->sidePaneShowText(); + setSelectionMode( KListBox::Single ); + viewport()->setBackgroundMode( PaletteBackground ); + setFrameStyle( QFrame::NoFrame ); + setHScrollBarMode( QScrollView::AlwaysOff ); + setAcceptDrops( true ); + + setFocusPolicy( NoFocus ); + + connect( this, SIGNAL( selectionChanged( QListBoxItem* ) ), + SLOT( slotExecuted( QListBoxItem* ) ) ); + connect( this, SIGNAL( rightButtonPressed( QListBoxItem*, const QPoint& ) ), + SLOT( slotShowRMBMenu( QListBoxItem*, const QPoint& ) ) ); + connect( this, SIGNAL( onItem( QListBoxItem * ) ), + SLOT( slotMouseOn( QListBoxItem * ) ) ); + connect( this, SIGNAL( onViewport() ), SLOT( slotMouseOff() ) ); + + mMapper = new QSignalMapper( this ); + connect( mMapper, SIGNAL( mapped( int ) ), SLOT( shortCutSelected( int ) ) ); + + QToolTip::remove( this ); + if ( !mShowText ) + new EntryItemToolTip( this ); + +} + +QSize Navigator::sizeHint() const +{ + return QSize( 100, 100 ); +} + +void Navigator::highlightItem( EntryItem * item ) +{ + mHighlightItem = item; + + setPaintActiveItem( mHighlightItem, true ); + + QTimer::singleShot( 2000, this, SLOT( slotStopHighlight() ) ); +} + +void Navigator::slotStopHighlight() +{ + setPaintActiveItem( mHighlightItem, false ); +} + +void Navigator::setSelected( QListBoxItem *item, bool selected ) +{ + // Reimplemented to avoid the immediate activation of + // the item. might turn out it doesn't work, we check that + // an confirm from MainWindow::selectPlugin() + if ( selected ) { + EntryItem *entry = static_cast<EntryItem*>( item ); + emit pluginActivated( entry->plugin() ); + } +} + +void Navigator::updatePlugins( QValueList<Kontact::Plugin*> plugins_ ) +{ + QValueList<Kontact::PluginProxy> plugins; + QValueList<Kontact::Plugin*>::ConstIterator end_ = plugins_.end(); + QValueList<Kontact::Plugin*>::ConstIterator it_ = plugins_.begin(); + for ( ; it_ != end_; ++it_ ) + plugins += PluginProxy( *it_ ); + + clear(); + + mActions.setAutoDelete( true ); + mActions.clear(); + mActions.setAutoDelete( false ); + + int counter = 0; + int minWidth = 0; + qBubbleSort( plugins ); + QValueList<Kontact::PluginProxy>::ConstIterator end = plugins.end(); + QValueList<Kontact::PluginProxy>::ConstIterator it = plugins.begin(); + for ( ; it != end; ++it ) { + Kontact::Plugin *plugin = ( *it ).plugin(); + if ( !plugin->showInSideBar() ) + continue; + + EntryItem *item = new EntryItem( this, plugin ); + item->setSelectable( !plugin->disabled() ); + + if ( item->width( this ) > minWidth ) + minWidth = item->width( this ); + + QString name = QString( "CTRL+%1" ).arg( counter + 1 ); + KAction *action = new KAction( plugin->title(), plugin->icon(), KShortcut( name ), + mMapper, SLOT( map() ), + mSidePane->actionCollection(), name.latin1() ); + mActions.append( action ); + mMapper->setMapping( action, counter ); + counter++; + } + + parentWidget()->setFixedWidth( minWidth ); +} + +void Navigator::dragEnterEvent( QDragEnterEvent *event ) +{ + kdDebug(5600) << "Navigator::dragEnterEvent()" << endl; + + dragMoveEvent( event ); +} + +void Navigator::dragMoveEvent( QDragMoveEvent *event ) +{ + kdDebug(5600) << "Navigator::dragEnterEvent()" << endl; + + kdDebug(5600) << " Format: " << event->format() << endl; + + QListBoxItem *item = itemAt( event->pos() ); + + if ( !item ) { + event->accept( false ); + return; + } + + EntryItem *entry = static_cast<EntryItem*>( item ); + + kdDebug(5600) << " PLUGIN: " << entry->plugin()->identifier() << endl; + + event->accept( entry->plugin()->canDecodeDrag( event ) ); +} + +void Navigator::dropEvent( QDropEvent *event ) +{ + kdDebug(5600) << "Navigator::dropEvent()" << endl; + + QListBoxItem *item = itemAt( event->pos() ); + + if ( !item ) { + return; + } + + EntryItem *entry = static_cast<EntryItem*>( item ); + + kdDebug(5600) << " PLUGIN: " << entry->plugin()->identifier() << endl; + + entry->plugin()->processDropEvent( event ); +} + +void Navigator::resizeEvent( QResizeEvent *event ) +{ + QListBox::resizeEvent( event ); + triggerUpdate( true ); +} + +void Navigator::enterEvent( QEvent *event ) +{ + // work around Qt behaviour: onItem is not emmitted in enterEvent() + KListBox::enterEvent( event ); + emit onItem( itemAt( mapFromGlobal( QCursor::pos() ) ) ); +} + +void Navigator::leaveEvent( QEvent *event ) +{ + KListBox::leaveEvent( event ); + slotMouseOn( 0 ); + mMouseOn = 0; +} + +void Navigator::slotExecuted( QListBoxItem *item ) +{ + if ( !item ) + return; + + EntryItem *entry = static_cast<EntryItem*>( item ); + + emit pluginActivated( entry->plugin() ); +} + +IconViewMode Navigator::sizeIntToEnum(int size) const +{ + switch ( size ) { + case int(LargeIcons): + return LargeIcons; + break; + case int(NormalIcons): + return NormalIcons; + break; + case int(SmallIcons): + return SmallIcons; + break; + default: + // Stick with sane values + return NormalIcons; + kdDebug() << "View mode not implemented!" << endl; + break; + } +} + +void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint &pos ) +{ + KPopupMenu menu; + menu.insertTitle( i18n( "Icon Size" ) ); + menu.insertItem( i18n( "Large" ), (int)LargeIcons ); + menu.setItemEnabled( (int)LargeIcons, mShowIcons ); + menu.insertItem( i18n( "Normal" ), (int)NormalIcons ); + menu.setItemEnabled( (int)NormalIcons, mShowIcons ); + menu.insertItem( i18n( "Small" ), (int)SmallIcons ); + menu.setItemEnabled( (int)SmallIcons, mShowIcons ); + + menu.setItemChecked( (int)mViewMode, true ); + menu.insertSeparator(); + + menu.insertItem( i18n( "Show Icons" ), (int)ShowIcons ); + menu.setItemChecked( (int)ShowIcons, mShowIcons ); + menu.setItemEnabled( (int)ShowIcons, mShowText ); + menu.insertItem( i18n( "Show Text" ), (int)ShowText ); + menu.setItemChecked( (int)ShowText, mShowText ); + menu.setItemEnabled( (int)ShowText, mShowIcons ); + int choice = menu.exec( pos ); + + if ( choice == -1 ) + return; + + if ( choice >= SmallIcons ) { + mViewMode = sizeIntToEnum( choice ); + Prefs::self()->setSidePaneIconSize( choice ); + } else { + // either icons or text were toggled + if ( choice == ShowIcons ) { + mShowIcons = !mShowIcons; + Prefs::self()->setSidePaneShowIcons( mShowIcons ); + QToolTip::remove( this ); + if ( !mShowText ) + new EntryItemToolTip( this ); + } else { + mShowText = !mShowText; + Prefs::self()->setSidePaneShowText( mShowText ); + QToolTip::remove( this ); + } + } + int maxWidth = 0; + QListBoxItem* it = 0; + for (int i = 0; (it = item(i)) != 0; ++i) + { + int width = it->width(this); + if (width > maxWidth) + maxWidth = width; + } + parentWidget()->setFixedWidth( maxWidth ); + + triggerUpdate( true ); +} + +void Navigator::shortCutSelected( int pos ) +{ + setCurrentItem( pos ); +} + +void Navigator::setHoverItem( QListBoxItem* item, bool hover ) +{ + static_cast<EntryItem*>( item )->setHover( hover ); + updateItem( item ); +} + +void Navigator::setPaintActiveItem( QListBoxItem* item, bool paintActive ) +{ + static_cast<EntryItem*>( item )->setPaintActive( paintActive ); + updateItem( item ); +} + +void Navigator::slotMouseOn( QListBoxItem* newItem ) +{ + QListBoxItem* oldItem = mMouseOn; + if ( oldItem == newItem ) return; + + if ( oldItem && !oldItem->isCurrent() && !oldItem->isSelected() ) + { + setHoverItem( oldItem, false ); + } + + if ( newItem && !newItem->isCurrent() && !newItem->isSelected() ) + { + setHoverItem( newItem, true ); + } + mMouseOn = newItem; +} + +void Navigator::slotMouseOff() +{ + slotMouseOn( 0 ); +} + +IconSidePane::IconSidePane( Core *core, QWidget *parent, const char *name ) + : SidePaneBase( core, parent, name ) +{ + mNavigator = new Navigator( this ); + connect( mNavigator, SIGNAL( pluginActivated( Kontact::Plugin* ) ), + SIGNAL( pluginSelected( Kontact::Plugin* ) ) ); + + setAcceptDrops( true ); +} + +IconSidePane::~IconSidePane() +{ +} + +void IconSidePane::updatePlugins() +{ + mNavigator->updatePlugins( core()->pluginList() ); +} + +void IconSidePane::selectPlugin( Kontact::Plugin *plugin ) +{ + bool blocked = signalsBlocked(); + blockSignals( true ); + + for ( uint i = 0; i < mNavigator->count(); ++i ) { + EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) ); + if ( item->plugin() == plugin ) { + mNavigator->setCurrentItem( i ); + break; + } + } + + blockSignals( blocked ); +} + +void IconSidePane::selectPlugin( const QString &name ) +{ + bool blocked = signalsBlocked(); + blockSignals( true ); + + for ( uint i = 0; i < mNavigator->count(); ++i ) { + EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) ); + if ( item->plugin()->identifier() == name ) { + mNavigator->setCurrentItem( i ); + break; + } + } + + blockSignals( blocked ); +} + +void IconSidePane::indicateForegrunding( Kontact::Plugin *plugin ) +{ + for ( uint i = 0; i < mNavigator->count(); ++i ) { + EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) ); + if ( item->plugin() == plugin ) { + mNavigator->highlightItem( item ); + break; + } + } + + +} +#include "iconsidepane.moc" + +// vim: sw=2 sts=2 et tw=80 diff --git a/kontact/src/iconsidepane.h b/kontact/src/iconsidepane.h new file mode 100644 index 000000000..281d25aec --- /dev/null +++ b/kontact/src/iconsidepane.h @@ -0,0 +1,193 @@ +/* + This file is part of the KDE Kontact. + + Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef KONTACT_ICONSIDEPANEBASE_H +#define KONTACT_ICONSIDEPANEBASE_H + +#include <qtooltip.h> + +#include <klistbox.h> + +#include "sidepanebase.h" +#include "prefs.h" + + +class QSignalMapper; + +namespace KParts { class Part; } + +namespace Kontact +{ + +class Core; +class Plugin; +class Navigator; + +enum IconViewMode { LargeIcons = 48, NormalIcons = 32, SmallIcons = 22, ShowText = 3, ShowIcons = 5 }; + + +/** + A QListBoxPixmap Square Box with an optional icon and a text + underneath. +*/ +class EntryItem : public QListBoxItem +{ + public: + EntryItem( Navigator *, Kontact::Plugin * ); + ~EntryItem(); + + Kontact::Plugin *plugin() const { return mPlugin; } + + const QPixmap *pixmap() const { return &mPixmap; } + + Navigator* navigator() const; + + void setHover( bool ); + void setPaintActive( bool ); + bool paintActive() const { return mPaintActive; } + /** + returns the width of this item. + */ + virtual int width( const QListBox * ) const; + /** + returns the height of this item. + */ + virtual int height( const QListBox * ) const; + + protected: + void reloadPixmap(); + + virtual void paint( QPainter *p ); + + private: + Kontact::Plugin *mPlugin; + QPixmap mPixmap; + bool mHasHover; + bool mPaintActive; +}; + +/** + * Tooltip that changes text depending on the item it is above. + * Compliments of "Practical Qt" by Dalheimer, Petersen et al. + */ +class EntryItemToolTip : public QToolTip +{ + public: + EntryItemToolTip( QListBox* parent ) + : QToolTip( parent->viewport() ), mListBox( parent ) + {} + protected: + void maybeTip( const QPoint& p ) { + // We only show tooltips when there are no texts shown + if ( Prefs::self()->sidePaneShowText() ) return; + if ( !mListBox ) return; + QListBoxItem* item = mListBox->itemAt( p ); + if ( !item ) return; + const QRect itemRect = mListBox->itemRect( item ); + if ( !itemRect.isValid() ) return; + + const EntryItem *entryItem = static_cast<EntryItem*>( item ); + QString tipStr = entryItem->text(); + tip( itemRect, tipStr ); + } + private: + QListBox* mListBox; +}; + +/** + Navigation pane showing all parts relevant to the user +*/ +class Navigator : public KListBox +{ + Q_OBJECT + public: + Navigator( SidePaneBase *parent = 0, const char *name = 0 ); + + virtual void setSelected( QListBoxItem *, bool ); + + void updatePlugins( QValueList<Kontact::Plugin*> plugins ); + + QSize sizeHint() const; + + void highlightItem( EntryItem* item ); + + IconViewMode viewMode() { return mViewMode; } + IconViewMode sizeIntToEnum(int size) const; + const QPtrList<KAction> & actions() { return mActions; } + bool showIcons() const { return mShowIcons; } + bool showText() const { return mShowText; } + signals: + void pluginActivated( Kontact::Plugin * ); + + protected: + void dragEnterEvent( QDragEnterEvent * ); + void dragMoveEvent ( QDragMoveEvent * ); + void dropEvent( QDropEvent * ); + void resizeEvent( QResizeEvent * ); + void enterEvent( QEvent* ); + void leaveEvent( QEvent* ); + + void setHoverItem( QListBoxItem*, bool ); + void setPaintActiveItem( QListBoxItem*, bool ); + + protected slots: + void slotExecuted( QListBoxItem * ); + void slotMouseOn( QListBoxItem *item ); + void slotMouseOff(); + void slotShowRMBMenu( QListBoxItem *, const QPoint& ); + void shortCutSelected( int ); + void slotStopHighlight(); + + private: + SidePaneBase *mSidePane; + IconViewMode mViewMode; + + QListBoxItem* mMouseOn; + + EntryItem* mHighlightItem; + + QSignalMapper *mMapper; + QPtrList<KAction> mActions; + bool mShowIcons; + bool mShowText; +}; + +class IconSidePane : public SidePaneBase +{ + Q_OBJECT + public: + IconSidePane( Core *core, QWidget *parent, const char *name = 0 ); + ~IconSidePane(); + + virtual void indicateForegrunding( Kontact::Plugin* ); + + public slots: + virtual void updatePlugins(); + virtual void selectPlugin( Kontact::Plugin* ); + virtual void selectPlugin( const QString &name ); + const QPtrList<KAction> & actions() { return mNavigator->actions(); } + + private: + Navigator *mNavigator; +}; + +} + +#endif diff --git a/kontact/src/kcmkontact.cpp b/kontact/src/kcmkontact.cpp new file mode 100644 index 000000000..0c518d5c8 --- /dev/null +++ b/kontact/src/kcmkontact.cpp @@ -0,0 +1,152 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include "kcmkontact.h" +#include "prefs.h" + + +#include <kaboutdata.h> +#include <kdebug.h> +#include <klistview.h> +#include <klocale.h> +#include <ktrader.h> + +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qlayout.h> + +#include <kdepimmacros.h> + +extern "C" +{ + KDE_EXPORT KCModule *create_kontactconfig( QWidget *parent, const char * ) { + return new KcmKontact( parent, "kcmkontact" ); + } +} + +class PluginItem : public QListViewItem +{ + public: + PluginItem( QListView *parent, const KService::Ptr &ptr ) + : QListViewItem( parent, ptr->name(), ptr->comment(), ptr->library() ), + mPtr( ptr ) + { + } + + KService::Ptr servicePtr() const + { + return mPtr; + } + + private: + KService::Ptr mPtr; +}; + +KcmKontact::KcmKontact( QWidget *parent, const char *name ) + : KPrefsModule( Kontact::Prefs::self(), parent, name ) +{ + QBoxLayout *topLayout = new QVBoxLayout( this ); + QBoxLayout *pluginStartupLayout = new QHBoxLayout( topLayout ); + topLayout->addStretch(); + + KPrefsWidBool *forceStartupPlugin = addWidBool( Kontact::Prefs::self()->forceStartupPluginItem(), this ); + pluginStartupLayout->addWidget( forceStartupPlugin->checkBox() ); + + PluginSelection *selection = new PluginSelection( Kontact::Prefs::self()->forcedStartupPluginItem(), this ); + addWid( selection ); + + pluginStartupLayout->addWidget( selection->comboBox() ); + selection->comboBox()->setEnabled( false ); + + connect( forceStartupPlugin->checkBox(), SIGNAL( toggled( bool ) ), + selection->comboBox(), SLOT( setEnabled( bool ) ) ); + load(); +} + +const KAboutData* KcmKontact::aboutData() const +{ + KAboutData *about = new KAboutData( I18N_NOOP( "kontactconfig" ), + I18N_NOOP( "KDE Kontact" ), + 0, 0, KAboutData::License_GPL, + I18N_NOOP( "(c), 2003 Cornelius Schumacher" ) ); + + about->addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" ); + about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" ); + + return about; +} + + +PluginSelection::PluginSelection( KConfigSkeleton::ItemString *item, QWidget *parent ) +{ + mItem = item; + mPluginCombo = new QComboBox( parent ); + connect( mPluginCombo, SIGNAL( activated( int ) ), SIGNAL( changed() ) ); +} + +PluginSelection::~PluginSelection() +{ +} + +void PluginSelection::readConfig() +{ + const KTrader::OfferList offers = KTrader::self()->query( + QString::fromLatin1( "Kontact/Plugin" ), + QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) ); + + int activeComponent = 0; + mPluginCombo->clear(); + for ( KService::List::ConstIterator it = offers.begin(); it != offers.end(); ++it ) { + KService::Ptr service = *it; + // skip summary only plugins + QVariant var = service->property( "X-KDE-KontactPluginHasPart" ); + if ( var.isValid() && var.toBool() == false ) + continue; + mPluginCombo->insertItem( service->name() ); + mPluginList.append( service ); + + if ( service->property("X-KDE-PluginInfo-Name").toString() == mItem->value() ) + activeComponent = mPluginList.count() - 1; + } + + mPluginCombo->setCurrentItem( activeComponent ); +} + +void PluginSelection::writeConfig() +{ + KService::Ptr ptr = *( mPluginList.at( mPluginCombo->currentItem() ) ); + mItem->setValue( ptr->property("X-KDE-PluginInfo-Name").toString() ); +} + +QValueList<QWidget *> PluginSelection::widgets() const +{ + QValueList<QWidget *> widgets; + widgets.append( mPluginCombo ); + + return widgets; +} + +#include "kcmkontact.moc" diff --git a/kontact/src/kcmkontact.h b/kontact/src/kcmkontact.h new file mode 100644 index 000000000..3b37f68f5 --- /dev/null +++ b/kontact/src/kcmkontact.h @@ -0,0 +1,69 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2003 Cornelius Scumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KCMKONTACT_H +#define KCMKONTACT_H + +#include <kprefsdialog.h> +#include <kservice.h> +#include "plugin.h" + +class QGroupBox; +class QComboBox; +class QListViewItem; + +class KAboutData; +class KListView; + +class KcmKontact : public KPrefsModule +{ + Q_OBJECT + + public: + KcmKontact( QWidget *parent = 0, const char *name = 0 ); + + virtual const KAboutData* aboutData() const; +}; + +class PluginSelection : public KPrefsWid +{ + Q_OBJECT + + public: + PluginSelection( KConfigSkeleton::ItemString *item, QWidget *parent ); + ~PluginSelection(); + + void readConfig(); + void writeConfig(); + + QValueList<QWidget *> widgets() const; + QComboBox *comboBox() const { return mPluginCombo; } + + private: + QComboBox *mPluginCombo; + QValueList<KService::Ptr> mPluginList; + KConfigSkeleton::ItemString *mItem; +}; + +#endif diff --git a/kontact/src/kontact.kcfg b/kontact/src/kontact.kcfg new file mode 100644 index 000000000..e8ae4eef1 --- /dev/null +++ b/kontact/src/kontact.kcfg @@ -0,0 +1,32 @@ +<?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="kontactrc"/> + + <group name="View"> + <entry type="String" name="ActivePlugin"> + <default>kontact_summaryplugin</default> + </entry> + <entry type="Bool" name="ForceStartupPlugin"> + <default>false</default> + <label>Always start with specified component:</label> + <whatsthis>Usually Kontact will come up with the component used before shutdown. Check this box if you would like a specific component to come up on start instead.</whatsthis> + </entry> + <entry type="String" name="ForcedStartupPlugin"> + </entry> + + <entry type="IntList" name="SidePaneSplitter"> + <default>1</default> + </entry> + + <entry type="Int" name="SidePaneIconSize"> + <default>32</default> + </entry> + <entry type="Bool" name="SidePaneShowIcons"><default>true</default></entry> + <entry type="Bool" name="SidePaneShowText"><default>true</default></entry> + <entry type="String" name="LastVersionSeen"> + </entry> + </group> +</kcfg> diff --git a/kontact/src/kontact.setdlg b/kontact/src/kontact.setdlg new file mode 100644 index 000000000..a90778a21 --- /dev/null +++ b/kontact/src/kontact.setdlg @@ -0,0 +1,646 @@ +[KontactSummary] +Name=Summary View +Name[bg]=Обобщение +Name[ca]=Vista de resum +Name[da]=Opsummeringsvisning +Name[de]=Übersicht +Name[el]=Προβολή σύνοψης +Name[es]=Vista de resumen +Name[et]=Kokkuvõttevaade +Name[fr]=Vue résumée +Name[is]=Yfirlitssýn +Name[it]=Vista sommario +Name[ja]=要約ビュー +Name[km]=ទិដ្ឋភាពសង្ខេប +Name[nds]=Översicht +Name[nl]=Overzichtsweergave +Name[pl]=Podsumowanie +Name[ru]=Просмотр сводок +Name[sr]=Приказ сажетка +Name[sr@Latn]=Prikaz sažetka +Name[sv]=Översiktsvy +Name[tr]=Özet Görünümü +Name[zh_CN]=摘要视图 +Name[zh_TW]=摘要檢視 +Comment=Configuration of Kontact's <b>Summary View</b>. Some plugins provide <i>Summary View</i> items, choose the ones you would like to list. +Comment[bg]=Настройване на <b>Обобщение</b> на Kontact. Някои приставки предлагат <i>обобщение</i>, изберете тези, които искате да използвате. +Comment[ca]=Configuració de la <b>vista de resum</b> del Kontact. Alguns endollables proporcionen elements de <i>vista de resum</i>, trieu-ne els que voldríeu llistar. +Comment[da]=Konfiguration af Kontacts <b>Opsummeringsvisning</b>. Nogle plugins giver <i>Opsummeringsvisning</i>-elementer, vælg dem du ønsker på listen. +Comment[de]=Einrichtung der <b>Zusammenfassungsansicht</b> von Kontact. Einige Kontact-Module stellen Elemente für die <i>Zusammenfassungsansicht</i> zur Verfügung. Wählen Sie hier, welche Elemente angezeigt werden sollen. +Comment[el]=Ρύθμιση της <b>Προβολής σύνοψης</b> του Kontact. Κάποια πρόσθετα παρέχουν αντικείμενα <i>Προβολή σύνοψης</i>· επιλέξτε αυτά που θέλετε να εμφανίζονται. +Comment[es]=Configuración de Kontact <b>Vista de resumen</b>. Algunos complementos proveen elementos para la <i>Vista de resumen</i>, elija los que quiera listar. +Comment[et]=Kontacti <b>kokkuvõttevaate</b> seadistamine. Mõned pluginad pakuvad <i>kokkuvõttevaate</i> elemente. Vali nimekirjas need, mida soovid näha. +Comment[fr]=Configuration de Kontact <b> Vue résumée</b>. Certains modules fournissent des éléments de <i>Vue Résumée</i>, choisissez ceux que vous voulez voir listés. +Comment[is]=Stillingar á <b>Yfirlitssýn</b>í Kontact. Sum íforrit koma með hluti í <i>Yfirlitssýn</i>, veldu þá sem þú vilt hafa á síðunni. +Comment[it]=Configurazione della <b>vista sommario</b> di Kontact. Alcuni plugin forniscono elementi di <i>vista sommario</i>, scegli quelli che desideri vedere nell'elenco. +Comment[ja]=Kontact の要約ビューの設定。要約ビューの項目を提供するプラグインがいくつかあります。要約ビューに表示させる項目を選択してください。 +Comment[km]=ការកំណត់រចនាសម្ព័ន្ធរបស់ Kontact <b>ទិដ្ឋភាពសង្ខេប</b> ។ កម្មវិធីជំនួយមួយចំនួនផ្ដល់នូវធាតុ<i>ទិដ្ឋភាពសង្ខេប</i> ជ្រើសទិដ្ឋភាពមួយក្នុងចំណោមទិដ្ឋភាពទាំងនេះដែលអ្នកចង់រាយ ។ +Comment[nds]=Kontact sien <b>Översicht</b> instellen. En Reeg Modulen stellt Indrääg för de <i>Översicht</i> praat. Hier kannst Du de utsöken, de Du hebben wullt. +Comment[nl]=Configuratie van Kontacts <b>Overzichtsweergave</b>. Sommige plugins bieden ook items aan voor de <i>Overzichtweergave</i>, kies welke u wilt zien. +Comment[pl]=Konfiguracja <b>Podsumowania</b> Kontaktu. Niektóre wtyczki zapewniają elementy <i>Widok podsumowania</i>, wybierz te które chcesz zobaczyć. +Comment[ru]=Настройка показа сводок различных компонентов. +Comment[sr]=Подешавање Kontact-овог <b>приказа сажетка</b>. Неки прикључци дају ставке <i>приказа сажетка</i>, изаберите оне које желите. +Comment[sr@Latn]=Podešavanje Kontact-ovog <b>prikaza sažetka</b>. Neki priključci daju stavke <i>prikaza sažetka</i>, izaberite one koje želite. +Comment[sv]=Inställning av Kontacts <b>översiktsvy</b>. Vissa insticksprogram tillhandahåller objekt för <i>översiktsvyn</i>. Välj de du skulle vilja visa. +Comment[zh_CN]=Kontact <b>摘要视图</b>配置。有些插件提供了<i>摘要视图</i>项目,请选择您希望出现在列表中的项目。 +Comment[zh_TW]=設定 Kontact 的摘要檢視。有些外掛程式會提供「摘要檢視」的項目,您可以選取您要列出的項目。 +Weight=100 +Icon=kontact_summary + +[KMail] +Name=E-Mail +Name[bg]=Е-поща +Name[ca]=Correu +Name[da]=E-mail +Name[el]=Αλληλογραφία +Name[es]=Correo electrónico +Name[et]=E-post +Name[fr]=Courriel +Name[is]=Tölvupóstur +Name[it]=Posta elettronica +Name[ja]=メール +Name[km]=អ៊ីមែល +Name[nds]=Nettpost +Name[nl]=E-mail +Name[pl]=E-mail +Name[pt_BR]=E-mail +Name[ru]=Электронная почта +Name[sk]=Pošta +Name[sr]=Е-пошта +Name[sr@Latn]=E-pošta +Name[sv]=E-post +Name[tr]=E-Posta +Name[zh_CN]=邮件 +Name[zh_TW]=電子郵件 +Comment=Configuration of Kontact's E-Mail Plugin <b>KMail</b>, includes a <i>Summary View Item</i> and represents a <i>Kontact Component</i>. +Comment[bg]=Настройване на приставката за <b>KMail</b> в Kontact, включително обобщението и компонента. +Comment[ca]=Configuració de l'endollable de correu <b>KMail</b> del Kontact, inclou un <i>element de vista de resum</i> i representa un <i>component del Kontact</i>. +Comment[da]=Konfiguration af Kontacts e-mail-plugin <b>KMail</b>, inkluderer et <i>Opsummeringsvisnings-element</i> og repræsenterer en <i>Kontact-komponent</i>. +Comment[de]=Einrichtung des E-Mail-Moduls <b>KMail</b> für Kontact. Die E-Mail-Komponente kann als <i>Kontact-Komponente<i> in die <i>Zusammenfassungsansicht</i> integriert werden. +Comment[el]=Η ρύθμιση του προσθέτου αλληλογραφίας <b>KMail</b> του Kontact, περιέχει ένα <i>Αντικείμενο προβολής σύνοψης</i> και αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>. +Comment[es]=Configuración del complemento de correo-e de Kontact <b>KMail</b>, incluye una <i>Vista de resumen</i> y representa un <i>Componente de Kontact</i>. +Comment[et]=Kontacti e-posti plugina <b>KMaili</b> seadistamine, mis sisaldab <i>kokkuvõttevaate elementi</i>. +Comment[fr]=Configuration du Module de Courriel de Kontact <b>KMail</b>, inclut un <i>Élément de Vue Résumée</i> et correspond à un <i>Composant de Kontact</i>. +Comment[is]=Stillingar fyrir tölvupóstíforrit Kontact <b>KMail</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>. +Comment[it]=Configurazione del plugin di posta elettronica <b>KMail</b> di Kontact, include una <i>vista sommario</i> e rappresenta un <i>componente Kontact</i>. +Comment[km]=ការកំណត់រចនាសម្ព័ន្ធរបស់កម្មវិធីជំនួយអ៊ីមែលរបស់ Kontact <b>KMail</b> រួមមាន<i>ធាតុទិដ្ឋភាពសង្ខេប</i> និងបង្ហាញ <i>សមាសភាគ Kontact</i> ។ +Comment[nds]=Kontact sien Nettpost-Moduul <b>KMail</b> instellen. Stellt en <i>Översicht-Indrag</i> praat un is en <i>Kontact-Komponent</i>. +Comment[nl]=Instellingen voor Kontacts e-mailplugin <b>KMail</b>. Bevat een <i>Overzichtsweergaveplugin</i> en een <i>Kontact-component</i>. +Comment[pl]=Konfiguracja wtyczki poczty Kontaktu <b>KMail</b>, zawiera <i>element Podsumowanie</i> i jest <i>Składnikiem Kontaktu</i>. +Comment[ru]=Настройка модуля электронной почты <b>KMail</b> для показа в виде сводки. +Comment[sr]=Подешавање Kontact-овог прикључка за е-пошту преко <b>KMail-</b>, укључујући <i>приказ сажетка</i>, и дат као <i>компонента Kontact-а</i>. +Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za e-poštu preko <b>KMail-</b>, uključujući <i>prikaz sažetka</i>, i dat kao <i>komponenta Kontact-a</i>. +Comment[sv]=Inställning av Kontacts e-postinsticksprogram <b>Kmail</b>, omfattar ett objekt för <i>översiktsvyn</i> och representerar en <i>Kontactkomponent</i>. +Comment[zh_CN]=Kontact <b>KMail</b> 电子邮件插件配置,其中包含一个<i>摘要视图项目,以 <i>Kontact 组件</i>形式呈现。 +Comment[zh_TW]=設定 Kontact 的電子郵件組件。 +Weight=200 +Icon=kontact_mail + +[KAB] +Name=Contacts +Name[af]=Kontakte +Name[ar]=المراسلون +Name[be]=Кантакты +Name[bg]=Контакти +Name[br]=Darempredoù +Name[bs]=Kontakti +Name[ca]=Contactes +Name[cs]=Kontakty +Name[cy]=Cysylltau +Name[da]=Kontakter +Name[de]=Kontakte +Name[el]=Επαφές +Name[eo]=Kontaktoj +Name[es]=Contactos +Name[et]=Kontaktid +Name[eu]=Kontaktuak +Name[fa]=تماسها +Name[fi]=Yhteystiedot +Name[fy]=Adressen +Name[ga]=Teagmhálacha +Name[gl]=Contactos +Name[he]=אנשי קשר +Name[hi]=सम्पर्कों +Name[hu]=Névjegyek +Name[is]=Tengiliðir +Name[it]=Contatti +Name[ja]=コンタクト +Name[ka]=კონტაქტები +Name[kk]=Контакттар +Name[km]=ទំនាក់ទំនង +Name[lt]=Kontaktai +Name[mk]=Контакти +Name[ms]=Orang hubungan +Name[nds]=Kontakten +Name[ne]=सम्पर्क +Name[nl]=Adressen +Name[nn]=Kontaktar +Name[pa]=ਸੰਪਰਕ +Name[pl]=Wizytówki +Name[pt]=Contactos +Name[pt_BR]=Contatos +Name[ro]=Contacte +Name[ru]=Контакты +Name[rw]=Amaderesi +Name[se]=Oktavuođat +Name[sk]=Kontakty +Name[sl]=Stiki +Name[sr]=Контакти +Name[sr@Latn]=Kontakti +Name[sv]=Kontakter +Name[ta]=தொடர்புகள் +Name[tg]=Алоқот +Name[th]=ที่อยู่ติดต่อ +Name[tr]=Kişiler +Name[uk]=Контакти +Name[uz]=Aloqalar +Name[uz@cyrillic]=Алоқалар +Name[zh_CN]=联系人 +Name[zh_TW]=聯絡人 +Comment=Configuration of Kontact's Adress Book Plugin <b>KAdressbook</b> which represents a <i>Kontact Component</i>. +Comment[bg]=Настройване на приставката за <b>KAdressbook</b> в Kontact, включително компонента. +Comment[ca]=Configuració de l'endollable de la llibreta d'adreces <b>KAdressbook</b> del Kontact, que representa un <i>component del Kontact</i>. +Comment[da]=Konfiguration af Kontacts adressebog-plugin <b>KAdressbook</b> som repræsenterer en <i>Kontact-komponent</i>. +Comment[de]=Einrichtung des Adressbuch-Moduls für Kontact, welches eine <i>Kontact-Komponente</i> repräsentiert. +Comment[el]=Ρύθμιση του πρόσθετου βιβλίου διευθύνσεων <b>KAdressbook</b> του Kontact που αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>. +Comment[es]=Configuración del complemento de libreta de direcciones de Kontact <b> KAddressbok</b>, el cual representa un <i>Componente de Kontact</i>. +Comment[et]=Kontacti aadressiraamatu plugina <b>KAdressbook</b> seaditamine. +Comment[fr]=Configuration du Module de Carnet d'Adresses de Kontact <b> KAdressbook</b> qui correspond à un <i>Composant de Kontact</i>. +Comment[is]=Stillingar fyrir vistfangaskráríforrit Kontact <b>KAdressbook</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>. +Comment[it]=Configurazione del plugin rubrica di <b>KAddressbook</b> che rappresenta un <i>componente Kontact</i>. +Comment[km]=ការកំណត់រចនាសម្ព័ន្ធរបស់កម្មវិធីជំនួយសៀវភៅអាសយដ្ឋានរបស់ Kontact <b>KAdressbook</b> ដែលបង្ហាញ <i>សមាសភាគ Kontact</i> ។ +Comment[nds]=Kontact sien Adressbook-Moduul <b>KAddressbook</b> instellende, dat en <i>Kontact-Komponent</i> is. +Comment[nl]=Instellingen voor Kontacts adresboekplugin <b>KMail</b>. Bevat een <i>Kontact-component</i>. +Comment[pl]=Konfiguracja wtyczki książki adresowej Kontaktu <b>KAddressBook</b>, która jest <i>Składnikiem Kontaktu</i>. +Comment[ru]=Настройка модуля адресной книги <b>KAdressbook</b> для показа в виде сводки. +Comment[sr]=Подешавање Kontact-овог прикључка за адресар преко <b>KAdressbook</b> у облику <i>компоненте Kontact-а</i>. +Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za adresar preko <b>KAdressbook</b> u obliku <i>komponente Kontact-a</i>. +Comment[sv]=Inställning av Kontacts adressboksinsticksprogram <b>Kaddressbook</b>, som representerar en <i>Kontactkomponent</i>. +Comment[zh_CN]=Kontact <b>KAdressbook</b> 地址簿插件配置,KAdressbook 以一个<i>Kontact 组件</i>形式呈现。 +Comment[zh_TW]=設定 Kontact 的通訊錄組件。 +Weight=300 +Icon=kontact_contacts + +[Special Dates] +Name=Special Dates Summary +Name[af]=Spesiale datums opsomming +Name[ar]=موجز عن التواريخ المرموقة +Name[bg]=Обобщение на специални случаи +Name[ca]=Resum de dates especials +Name[cs]=Souhrn speciálních datumů +Name[da]=Opsummering af særlige datoer +Name[de]=Übersicht über besondere Termine +Name[el]=Σύνοψη σημαντικών ημερομηνιών +Name[eo]=Resumo pri Specialaj Datoj +Name[es]=Resumen de fechas especiales +Name[et]=Tähtpäevade kokkuvõte +Name[eu]=Data berezien laburpena +Name[fa]=خلاصۀ تاریخهای ویژه +Name[fi]=Erikoispäivien yhteenveto +Name[fr]=Résumé des dates particulières +Name[fy]=Oersicht foar spesjale datums +Name[gl]=Resumo de Datas Especiais +Name[he]=תקציר תאריכים מיוחדים +Name[hu]=A fontos dátumok áttekintője +Name[is]=Yfirlit sérstakra daga +Name[it]=Sommario date speciali +Name[ja]=特別な日の要約 +Name[ka]=განსაკუთრებულ თარიღთა დაიჯესტი +Name[kk]=Ерекше күндер тұжырымы +Name[km]=សង្ខេបថ្ងៃពិសេស +Name[lt]=Ypatingų dienų santrauka +Name[mk]=Преглед на специјални датуми +Name[ms]=Ringkasan Tarikh Khusus +Name[nb]=Sammendrag av spesielle datoer +Name[nds]=Översicht över besünner Daag +Name[ne]=विशेष मिति सारांश +Name[nl]=Overzicht voor speciale data +Name[nn]=Samandrag for spesielle datoar +Name[pl]=Podsumowanie dat specjalnych +Name[pt]=Sumário de Datas Especiais +Name[pt_BR]=Resumo de Datas Especiais +Name[ru]=Сводка особых дат +Name[sk]=Súhrn špeciálnych dátumov +Name[sl]=Povzetek posebnih datumov +Name[sr]=Сажетак посебних датума +Name[sr@Latn]=Sažetak posebnih datuma +Name[sv]=Översikt av speciella datum +Name[ta]=விசேஷ செய்திகளின் சுருக்கம் +Name[th]=สรุปวันพิเศษ +Name[tr]=Özel Tarihler Özeti +Name[uk]=Короткий підсумок особливих дат +Name[zh_CN]=特殊日期摘要 +Name[zh_TW]=特殊日期摘要 +Comment=Special Dates Summary Component +Comment[af]=Spesiale datums opsomming komponent +Comment[bg]=Модул за обобщение на специалните случаи +Comment[ca]=Component pel resum de dates especials +Comment[cs]=Komponenta souhrnu speciálních příležitostí +Comment[da]=Opsummeringskomponent for særlige datoer +Comment[de]=Komponente für Übersicht über besondere Termine +Comment[el]=Στοιχείο σύνοψης Σημαντικών Ημερομηνιών +Comment[eo]=Specialdatresuma Komponanto +Comment[es]=Componente de resumen de fechas especiales +Comment[et]=Tähtpäevade kokkuvõtte komponent +Comment[eu]=Data berezien laburpenaren osagaia +Comment[fa]=مؤلفۀ خلاصۀ تاریخهای ویژه +Comment[fi]=Erikoispäivien yhteenvedon komponentti +Comment[fr]=Composant de résumé des dates particulières +Comment[fy]=Komponint foar oersicht fan spesjale datums +Comment[gl]=Compoñente de Resumo de Datas Especiais +Comment[he]=רכיב תאריכים חשובים +Comment[hu]=A fontos dátumok áttekintő komponense +Comment[is]=Yfirlitshluti sérstakra daga +Comment[it]=Componente sommario per le date speciali +Comment[ja]=特別な日の要約コンポーネント +Comment[ka]=განაკუთრებულ თარიღთა დაიჯესტის კომპონენტი +Comment[kk]=Ерекше күндер тұжырымының компоненті +Comment[km]=សមាសភាគសង្ខេបនៃថ្ងៃពិសេស +Comment[lt]=Ypatingų dienų santraukos komponentas +Comment[mk]=Компонента за преглед на специјални датуми +Comment[ms]=Komponen Ringkasan Tarikh Khusus +Comment[nb]=Komponent for sammendrag av spesielle datoer +Comment[nds]=Översichtkomponent för besünner Daag +Comment[ne]=विशेष मिति सारांश अवयव +Comment[nl]=Component voor overzicht van speciale data +Comment[nn]=Komponent for samandrag for spesielle datoar +Comment[pl]=Składnik podsumowania dat specjalnych +Comment[pt]=Componente de Sumário de Datas Especiais +Comment[pt_BR]=Componente de Datas Especiais +Comment[ru]=Компонент сводки особых дат +Comment[sk]=Komponent súhrnu špeciálnych dátumov +Comment[sl]=Komponenta za povzetke posebnih datumov +Comment[sr]=Компонента сажетка посебних датума +Comment[sr@Latn]=Komponenta sažetka posebnih datuma +Comment[sv]=Komponent för översikt av speciella datum +Comment[ta]=விசேஷ தேதிகள் சுருக்கப் பகுதி +Comment[tr]=Özel Tarihler Özeti Bileşeni +Comment[uk]=Компонент короткого підсумку особливих дат +Comment[zh_CN]=特殊日期摘要组件 +Comment[zh_TW]=特殊日期摘要元件 +Weight=310 +Icon=cookie + +[KOrganizer] +Name=Calendar +Name[af]=Kalender +Name[ar]=التقويم +Name[be]=Каляндар +Name[bg]=Календар +Name[br]=Deiziadur +Name[bs]=Kalendar +Name[ca]=Calendari +Name[cs]=Kalendář +Name[cy]=Calendr +Name[da]=Kalender +Name[de]=Kalender +Name[el]=Ημερολόγιο +Name[eo]=Kalendaro +Name[es]=Calendario +Name[et]=Kalender +Name[eu]=Egutegia +Name[fa]=تقویم +Name[fi]=Kalenteri +Name[fr]=Calendrier +Name[fy]=Aginda +Name[ga]=Féilire +Name[gl]=Calendario +Name[he]=לוח שנה +Name[hi]=कैलेन्डर +Name[hu]=Naptár +Name[is]=Dagatal +Name[it]=Calendario +Name[ja]=カレンダー +Name[ka]=კალენდარი +Name[kk]=Күнтізбе +Name[km]=ប្រតិទិន +Name[lt]=Kalendorius +Name[mk]=Календар +Name[ms]=Kalendar +Name[nb]=Kalender +Name[nds]=Kalenner +Name[ne]=क्यालेन्डर +Name[nl]=Agenda +Name[nn]=Kalender +Name[pa]=ਕੈਲੰਡਰ +Name[pl]=Kalendarz +Name[pt]=Calendário +Name[pt_BR]=Calendário +Name[ru]=Календарь +Name[se]=Kaleandar +Name[sk]=Kalendár +Name[sl]=Koledar +Name[sr]=Календар +Name[sr@Latn]=Kalendar +Name[sv]=Kalender +Name[ta]=நாள்காட்டி +Name[tg]=Тақвим +Name[th]=บันทึกประจำวัน +Name[tr]=Takvim +Name[uk]=Календар +Name[uz]=Kalendar +Name[uz@cyrillic]=Календар +Name[zh_CN]=日历 +Name[zh_TW]=行事曆 +Comment=Configuration of Kontact's Calendar Plugin <b>KOrganizer</b>, includes a <i>Summary View Item</i> and represents a <i>Kontact Component</i>. +Comment[bg]=Настройване на приставката за <b>KOrganizer</b> в Kontact, включително <i>обобщението</i> и <i>компонента</i>. +Comment[ca]=Configuració de l'endollable de calendari <b>KOrganizer</b> del Kontact, inclou un <i>element de vista de resum</i> i representa un <i>component del Kontact</i>. +Comment[da]=Konfiguration af Kontacts kalender-plugin <b>KOrganizer</b>, inkluderer et <i>Opsummeringsvisningselement</i> og repræsenterer en <i>Kontact-komponent</i>. +Comment[de]=Einrichtung des Kalender-Moduls <b>KOrganizer</b> für Kontact, einschließlich der <i>Zusammenfassungsansicht</i>; repräsentiert eine <i>Kontact-Komponente</i> +Comment[el]=Η ρύθμιση του προσθέτου ημερολογίου του <b>KOrganizer</b> του Kontact, περιέχει ένα <i>Αντικείμενο προβολής σύνοψης</i> και αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>. +Comment[es]=Configuración del complemento de calendario de Kontact, <b> KOrganizer</b>, incluye una <i>Vista de resumen</i> y representa un <i>Componente de Kontact</i>. +Comment[et]=Kontacti kalendriplugina <b>KOrganizeri</b> seadistamine, mis sisaldab <i>kokkuvõttevaate elementi</i>. +Comment[fr]=Configuration du Module de Calendrier de Kontact <b>KOrganizer</b>, inclut un <i>Élément de Vue Résumée</i> et correspond à un <i>Composant de Kontact</i>. +Comment[is]=Stillingar fyrir dagatalsíforrit Kontact <b>KOrganizer</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>. +Comment[it]=Configurazione del plugin calendario <b>KOrganizer</b> di Kontact, include una <i>vista sommario</i> e rappresenta un <i>componente Kontact</i>. +Comment[km]=ការកំណត់រចនាសម្ព័ន្ធរបស់កម្មវិធីជំនួយប្រតិទិនរបស់ Kontact <b>KOrganizer</b>រួមមាន <i>ធាតុទិដ្ឋភាពសង្ខេប</i> និងបង្ហាញ <i>សមាសភាគ Kontact</i>. +Comment[nds]=Kontact sien Kalenner-Moduul <b>KOrganizer</b> instellen. Stellt en <i>Översicht-Indrag</i> praat un is en <i>Kontact-Komponent</i>. +Comment[nl]=Instellingen voor Kontacts agendaplugin <b>KOrganizer</b>. Bevat een <i>Overzichtsweergaveplugin</i> en een <i>Kontact-component</i>. +Comment[pl]=Konfiguracja wtyczki kalendarza Kontaktu <b>KOrganizer</b>, zawiera <i>element Podsumowanie</i> i jest <i>Składnikiem Kontaktu</i>. +Comment[ru]=Настройка модуля календаря <b>KOrganizer</b> для показа в виде сводки. +Comment[sr]=Подешавање Kontact-овог прикључка за календар преко <b>KOrganizer-а</b>, укључујући <i>приказ сажетка</i>, и дат као <i>компонента Kontact-а</i>. +Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za kalendar preko <b>KOrganizer-a</b>, uključujući <i>prikaz sažetka</i>, i dat kao <i>komponenta Kontact-a</i>. +Comment[sv]=Inställning av Kontacts kalenderinsticksprogram <b>Korganizer</b>, omfattar ett objekt för <i>översiktsvyn</i> och representerar en <i>Kontactkomponent</i>. +Comment[zh_CN]=Kontact 日历插件配置,<b>KOrganizer</b> 包含一个<i>摘要视图项目</i>,以 <i>Kontact 组件</i>形式呈现。 +Comment[zh_TW]=設定 Kontact 的行事曆組件。 +Weight=400 +Icon=kontact_date + +[KNode] +Name=News +Name[af]=Nuus +Name[ar]=الأخبار +Name[be]=Навіны +Name[bg]=Новини +Name[br]=Keleier +Name[bs]=Usenet +Name[ca]=Notícies +Name[cs]=Novinky +Name[cy]=Newyddion +Name[da]=Nyheder +Name[de]=Usenet +Name[el]=Νέα +Name[eo]=Novaĵoj +Name[es]=Noticias +Name[et]=Uudisegrupid +Name[eu]=Berriak +Name[fa]=اخبار +Name[fi]=Uutiset +Name[fr]=Nouvelles +Name[fy]=Nijs +Name[ga]=Nuacht +Name[gl]=Novas +Name[he]=חדשות +Name[hi]=समाचार +Name[hu]=Hírek +Name[is]=Fréttir +Name[ja]=ニュース +Name[ka]=სიახლეები +Name[kk]=Жаңалықтар +Name[km]=ព័ត៌មាន +Name[lt]=Naujienos +Name[mk]=Вести +Name[ms]=Berita +Name[nb]=Njus +Name[nds]=Narichten +Name[ne]=समाचार +Name[nl]=Nieuws +Name[nn]=Nyheiter +Name[pa]=ਖ਼ਬਰਾਂ +Name[pl]=Listy dyskusyjne +Name[pt]=Notícias +Name[pt_BR]=Notícias +Name[ro]=Ştiri +Name[ru]=Новости +Name[se]=Ođđasat +Name[sk]=Diskusné skupiny +Name[sl]=Novice +Name[sr]=Вести +Name[sr@Latn]=Vesti +Name[sv]=Nyheter +Name[ta]=செய்திகள் +Name[tg]=Ахборот +Name[th]=ข่าว +Name[tr]=Haberler +Name[uk]=Новини +Name[uz]=Yangiliklar +Name[uz@cyrillic]=Янгиликлар +Name[zh_CN]=新闻 +Name[zh_TW]=新聞 +Comment=Configuration of Kontact's News Plugin <b>KNode</b> which represents a <i>Kontact Component</i>. +Comment[bg]=Настройване на приставката за <b>KNode</b> в Kontact, включително компонента. +Comment[ca]=Configuració de l'endollable de notícies <b>KNode</b> del Kontact, que representa un <i>component del Kontact</i>. +Comment[da]=Konfiguration af Kontacts nyheds-plugin <b>KNode</b> som repræsenterer en <i>Kontact-komponent</i>. +Comment[de]=Einrichtung des News-Moduls <b>KNode</b> für Kontact; repräsentiert eine <i>Kontact-Komponente</i> +Comment[el]=Ρύθμιση του πρόσθετου νέων <b>KNode</b> του Kontact που αντιπροσωπεύει ένα <i>Συστατικό του Kontact</i>. +Comment[es]=Configuración del complemento de noticias de Kontact <b>KNode</b> , el cual representa un <i>Componente de Kontact</i>. +Comment[et]=Kontacti uudisteplugina <b>KNode</b> seadistamine. +Comment[fr]=Configuration du Module de Nouvelles de Kontact <b>KNode</b> qui correspond à un <i>Composant de Kontact</i>. +Comment[is]=Stillingar fyrir fréttastraumsíforrit Kontact <b>KNode</b>, inniheldur <i>yfirlitssýnarhlut</i> sem stendur fyrir <i>Kontact einingu</i>. +Comment[it]=Configurazione del plugin notizie <b>KNode</b> di Kontact, che rappresenta un <i>componente Kontact</i>. +Comment[km]=ការកំណត់រចនាសម្ព័ន្ធរបស់កម្មវិធីជំនួយព័ត៌មានរបស់ Kontact <b>KNode</b> ដែលបង្ហាញ <i>សមាភាគរបស់ Kontact</i> ។ +Comment[nds]=Kontact sien Narichten-Moduul <b>KNode</b> instellen, dat en <i>Kontact-Komponent</i> is. +Comment[nl]=Instellingen voor Kontacts nieuwsplugin <b>KNode</b>. Bevat een <i>Kontact-component</i>. +Comment[pl]=Konfiguracja wtyczki wiadomości Kontaktu <b>KNode</b>, która jest <i>składnikiem Kontaktu</i>. +Comment[ru]=Настройка модуля новостей <b>KNode</b> для показа в виде сводки. +Comment[sr]=Подешавање Kontact-овог прикључка за вести преко <b>KNode-а</b> у облику <i>компненте Kontact-а</i>. +Comment[sr@Latn]=Podešavanje Kontact-ovog priključka za vesti preko <b>KNode-a</b> u obliku <i>kompnente Kontact-a</i>. +Comment[sv]=Inställning av Kontacts nyhetsinsticksprogram <b>Knode</b>, som representerar en <i>Kontactkomponent</i>. +Comment[zh_CN]=Kontact 新闻组插件配置,<b>KNode</b> 以一个 <i>Kontact 组件</i>形式呈现。 +Comment[zh_TW]=設定 Kontact 的新聞組件。 +Weight=500 +Icon=kontact_news + +[KWeather] +Name=Weather +Name[af]=Weer +Name[ar]=الطقس +Name[be]=Надвор'е +Name[bg]=Време +Name[br]=Amzer +Name[bs]=Vrijeme +Name[ca]=Temps +Name[cs]=Počasí +Name[cy]=Tywydd +Name[da]=Vejr +Name[de]=Wetter +Name[el]=Καιρός +Name[eo]=Vetero +Name[es]=Meteorología +Name[et]=Ilm +Name[eu]=Eguraldia +Name[fa]=آب و هوا +Name[fi]=Sää +Name[fr]=Météo +Name[fy]=It waar +Name[ga]=Aimsir +Name[gl]=O Tempo +Name[he]=מזג אוויר +Name[hi]=वेदर +Name[hu]=Időjárás +Name[is]=Veður +Name[it]=Tempo meteorologico +Name[ja]=気象情報 +Name[ka]=ამინდი +Name[kk]=Ауа райы +Name[km]=អាកាសធាតុ +Name[lt]=Orų pranešėjas +Name[mk]=Време +Name[ms]=Cuaca +Name[nb]=Været +Name[nds]=Weder +Name[ne]=मौसम +Name[nl]=Het weer +Name[nn]=Vêrmelding +Name[pl]=Pogoda +Name[pt]=Meteorologia +Name[pt_BR]=Tempo +Name[ro]=Vreme +Name[ru]=Погода +Name[se]=Dáldedieđáhus +Name[sk]=Počasie +Name[sl]=Vreme +Name[sr]=Време +Name[sr@Latn]=Vreme +Name[sv]=Väder +Name[ta]=வானிலை +Name[tg]=Пешгӯии ҳаво +Name[th]=รายงานอากาศ +Name[tr]=Hava Durumu +Name[uk]=Погода +Name[uz]=Ob-havo +Name[uz@cyrillic]=Об-ҳаво +Name[zh_CN]=天气 +Name[zh_TW]=天氣 +Comment=Weather Information Component +Comment[bg]=Информация за времето +Comment[ca]=Component d'informació del temps +Comment[da]=Komponent til vejrinformation +Comment[de]=Komponente für Wetterinformationen +Comment[el]=Συστατικό πληροφοριών καιρού +Comment[es]=Componente de información meteorológica +Comment[et]=Ilmateate komponent +Comment[fr]=Composant d'Informations météorologiques +Comment[is]=Eining fyrir veðurupplýsingar +Comment[it]=Informazioni meteorologiche +Comment[ja]=気象情報コンポーネント +Comment[km]=សមាសភាគព័ត៌មានអាកាសធាតុ +Comment[nds]=Wederinformatschonen-Komponent +Comment[nl]=Weerinformatiecomponent +Comment[pl]=Składnik informacji o pogodzie +Comment[ru]=Информация о погоде +Comment[sk]=Informácie o počasí +Comment[sr]=Компонента информација о времену +Comment[sr@Latn]=Komponenta informacija o vremenu +Comment[sv]=Komponent med väderrapport +Comment[tr]=Hava Durumu Bilgisi Bileşeni +Comment[zh_CN]=天气信息组件 +Comment[zh_TW]=天氣資訊組件 +Weight=1000 +Icon=kweather + +[NewsTicker] +Name=News Ticker +Name[af]=Nuus tikker +Name[az]=Xəbər Gözləyici +Name[br]=Kliker keleier +Name[ca]=Teletip de notícies +Name[cy]=Ticer Newyddion +Name[da]=Nyhedstelegraf +Name[de]=Newsticker +Name[el]=Προβολέας ειδήσεων +Name[eo]=Novaĵprezentilo +Name[es]=Teletipo de noticias +Name[et]=Uudistejälgija +Name[eu]=Berri markatzailea +Name[fa]=Ticker اخبار +Name[fi]=Uutisnäytin +Name[fr]=Téléscripteur de nouvelles +Name[fy]=Nijs Tikker +Name[gl]=Colector de Novas +Name[he]=חדשות רצות +Name[hi]=न्यूज टिकर +Name[hr]=Ticker sa novostima +Name[hu]=RSS hírmegjelenítő +Name[id]=Ticker Berita +Name[is]=Fréttastrimill +Name[it]=Ticker notizie +Name[ja]=ニュースティッカー +Name[ka]=სიახლეთა ტიკერი +Name[kk]=Жаңалық таспасы +Name[km]=កម្មវិធីទទួលព័ត៌មាន +Name[lt]=News pranešėjas +Name[lv]=Ziņu Tikkers +Name[ms]=Pengetik Berita +Name[nb]=Nyhetstelegraf +Name[nds]=Narichten-Ticker +Name[ne]=न्यूज टिकर +Name[nn]=Nyheitstelegraf +Name[pl]=Wiadomości +Name[pt]=Extractor de Notícias +Name[pt_BR]=Animação de Notícias +Name[ro]=Ştiri Internet +Name[ru]=Новости +Name[sk]=Sledovanie správ +Name[sl]=Prikazovalnik novic +Name[sr]=Откуцавач вести +Name[sr@Latn]=Otkucavač vesti +Name[sv]=Nyhetsövervakare +Name[ta]=செய்திகள் குறிப்பான் +Name[tg]=Ахборот +Name[th]=ตั๋วข่าว +Name[tr]=Haber İzleyici +Name[uk]=Стрічка новин +Name[ven]=Musengulusi wa Mafhungo +Name[vi]=Trình kiểm tra news +Name[xh]=Umchola-choli weendaba +Name[zh_CN]=新闻点点通 +Name[zh_TW]=新聞顯示器 +Name[zu]=Umlungiseleli Wezindaba +Comment=News Ticker Component +Comment[af]=Nuus tikker komponent +Comment[bg]=Компонент за новини +Comment[ca]=Component de teletip de notícies +Comment[cs]=Komponenta zdrojů novinek +Comment[da]=Nyhedstelegraf-komponent +Comment[de]=Newsticker-Komponente +Comment[el]=Συστατικό προβολέα ειδήσεων +Comment[eo]=Novaĵprezentila Komponanto +Comment[es]=Componente de teletipo de noticias +Comment[et]=Uudistejälgija komponent +Comment[eu]=Berri markatzaile osagaia +Comment[fa]=مؤلفۀ Ticker اخبار +Comment[fi]=Uutiskomponentti +Comment[fr]=Composant d'affichage de nouvelles +Comment[fy]=Nijstikkerkomponint +Comment[gl]=Compoñente de Fonte de Novas +Comment[hu]=Hírmegjelenítő komponens +Comment[is]=Fréttastrimilshluti +Comment[it]=Ticker notizie +Comment[ja]=ニュースティッカーコンポーネント +Comment[ka]=სიახლეთა ტიკერის კომპონენტი +Comment[kk]=Жаңалық таспасының компоненті +Comment[km]=សមាសភាគកម្មវិធីទទួលព័ត៌មាន +Comment[lt]=Naujienų pranešėjo komponentas +Comment[ms]=Komponen Pengetik Berita +Comment[nb]=Komponent for Nyhetstelegraf +Comment[nds]=Narichtentelegraaf-Komponent +Comment[ne]=समाचार टिकर अवयव +Comment[nl]=Newstickercomponent +Comment[nn]=Nyhendetelegrafkomponent +Comment[pl]=Składnik paska wiadomości +Comment[pt]=Componente de Fontes de Notícias +Comment[pt_BR]=Componente Mostrador de Notícias +Comment[ru]=Компонент ленты новостей +Comment[sk]=Komponent zdrojov správ +Comment[sl]=Komponenta prikazovalnika novic +Comment[sr]=Компонента откуцавача вести +Comment[sr@Latn]=Komponenta otkucavača vesti +Comment[sv]=Nyhetskomponent +Comment[ta]=செய்தி எடுக்கும் பகுதி +Comment[tr]=Haber İzleyici Bileşeni +Comment[uk]=Компонент смужки новин +Comment[zh_CN]=新闻点点通组件 +Comment[zh_TW]=新聞顯示元件 +Weight=1100 +Icon=knode diff --git a/kontact/src/kontactconfig.desktop b/kontact/src/kontactconfig.desktop new file mode 100644 index 000000000..b057e72c4 --- /dev/null +++ b/kontact/src/kontactconfig.desktop @@ -0,0 +1,53 @@ +[Desktop Entry] +Exec=kcmshell kontactconfig +Icon=kontact +Type=Service +ServiceTypes=KCModule + +X-KDE-ModuleType=Library +X-KDE-Library=kontact +X-KDE-FactoryName=kontactconfig +X-KDE-HasReadOnlyMode=false +X-KDE-ParentApp=kontact +X-KDE-ParentComponents=kontact +X-KDE-Weight=0 + +Name=Kontact +Name[be]=Кантакт +Name[hi]=कॉन्टेक्ट +Name[mk]=Контакт +Name[ne]=सम्पर्क गर्नुहोस् +Name[sv]=Kontakt +Name[ta]=தொடர்பு கொள் +Name[zh_TW]=Kontact 個人資訊管理 +Comment=KDE Kontact +Comment[bg]=Управление на личната информация +Comment[ca]=Kontact de KDE +Comment[cy]=Kontact KDE +Comment[de]=Kontact +Comment[fi]=Kontact +Comment[hi]=केडीई कॉन्टेक्ट +Comment[mk]=KDE Контакт +Comment[ms]=Kontact KDE +Comment[nds]=KDE-Kontact +Comment[ne]=केडीई सम्पर्क +Comment[pl]=Kontact dla KDE +Comment[pt]=Kontact do KDE +Comment[pt_BR]=Kontact do KDE +Comment[ro]=Contact KDE +Comment[ta]=கேடிஇ தொடர்புகொள் +Keywords=kontact +Keywords[be]=кантакт,kontact +Keywords[bg]=контакти, връзка, информация, личен, поща, бизнес, планиране, kontact +Keywords[de]=Kontact +Keywords[hi]=कॉन्टेक्ट +Keywords[hu]=kapcsolat +Keywords[mk]=kontact,контакт +Keywords[nb]=kontact, kontakt +Keywords[nds]=Kontact +Keywords[ne]=सम्पर्क +Keywords[sr]=kontact, контакт +Keywords[sr@Latn]=kontact, kontakt +Keywords[sv]=kontakt +Keywords[ta]=தொடர்புகொள் +Keywords[tr]=bağlantı diff --git a/kontact/src/kontactdcop.desktop b/kontact/src/kontactdcop.desktop new file mode 100644 index 000000000..fdd07b9cc --- /dev/null +++ b/kontact/src/kontactdcop.desktop @@ -0,0 +1,18 @@ +[Desktop Entry] +Name=Kontact +Name[be]=Кантакт +Name[hi]=कॉन्टेक्ट +Name[mk]=Контакт +Name[ne]=सम्पर्क गर्नुहोस् +Name[sv]=Kontakt +Name[ta]=தொடர்பு கொள் +Name[zh_TW]=Kontact 個人資訊管理 +Exec=kontact --iconify +Type=Application +Icon=kontact +NoDisplay=true +X-DCOP-ServiceType=Unique +X-DCOP-ServiceName=kontact +ServiceTypes=DCOP/ResourceBackend/IMAP,DCOP/Mailer +X-KDE-StartupNotify=false +Categories=Qt;KDE;Office diff --git a/kontact/src/kontactiface.h b/kontact/src/kontactiface.h new file mode 100644 index 000000000..7af3e8a5c --- /dev/null +++ b/kontact/src/kontactiface.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2007 Volker Krause <vkrause@kde.org> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef KONTACT_INTERFACE_H +#define KONTACT_INTERFACE_H + +#include <dcopobject.h> + +class KontactIface : public DCOPObject +{ + K_DCOP + public: + KontactIface() : DCOPObject("KontactIface") {} + + k_dcop: + virtual void selectPlugin( const QString &name ) = 0; + +}; + +#endif diff --git a/kontact/src/kontactui.rc b/kontact/src/kontactui.rc new file mode 100644 index 000000000..8c68f0607 --- /dev/null +++ b/kontact/src/kontactui.rc @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!DOCTYPE gui SYSTEM "kpartgui.dtd"> +<gui version="22" name="kontact" > +<MenuBar> + <Menu name="file" noMerge="1"> + <text>&File</text> + <Merge/> + <Separator/> + <Action name="action_new"/> + <Separator/> + <Action name="file_quit"/> + <Merge/> + </Menu> + <Merge /> + <Menu name="settings"> + <text>&Settings</text> + <Merge append="save_merge"/> +<!-- <Separator/> --> + <DefineGroup name="settings_configure" append="configure_merge"/> + <Action name="settings_configure_kontact" append="configure_merge"/> + <Action name="settings_configure_kontact_profiles" append="configure_merge"/> + +<!-- Those actions have to be set by the parts because some applications + have app.rc == part.rc +--> +<!-- + <Action name="options_configure_keybinding"/> + <Action name="options_configure_toolbars"/> +--> + </Menu> + <Menu name="help"><text>&Help</text> + <Action name="help_introduction"/> + <Action name="help_tipofday"/> + <Separator/> + <Action name="help_requestfeature"/> + </Menu> +</MenuBar> +<ToolBar position="Top" noMerge="1" name="mainToolBar"><text>Main Toolbar</text> + <Action name="action_new"/> + <Action name="action_sync"/> + <Merge/> + <Action name="help_whats_this"/> +</ToolBar> +<ToolBar position="Top" hidden="true" name="navigatorToolBar"><text>Navigator</text> + <Action name="navigator_spacer_item"/> + <ActionList name="navigator_actionlist" /> +</ToolBar> +</gui> diff --git a/kontact/src/main.cpp b/kontact/src/main.cpp new file mode 100644 index 000000000..d3fce17c2 --- /dev/null +++ b/kontact/src/main.cpp @@ -0,0 +1,168 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <iostream> + +#include <dcopclient.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kstartupinfo.h> +#include <kuniqueapplication.h> +#include <kwin.h> +#include <kstandarddirs.h> +#include <ktrader.h> +#include "plugin.h" + +#include <qlabel.h> +#include "prefs.h" + +#include "alarmclient.h" +#include "mainwindow.h" +#include <uniqueapphandler.h> // in ../interfaces + +using namespace std; + +static const char description[] = + I18N_NOOP( "KDE personal information manager" ); + +static const char version[] = "1.2.9"; + +class KontactApp : public KUniqueApplication { + public: + KontactApp() : mMainWindow( 0 ), mSessionRestored( false ) {} + ~KontactApp() {} + + int newInstance(); + void setMainWindow( Kontact::MainWindow *window ) { + mMainWindow = window; + setMainWidget( window ); + } + void setSessionRestored( bool restored ) { + mSessionRestored = restored; + } + + private: + void startKOrgac(); + Kontact::MainWindow *mMainWindow; + bool mSessionRestored; +}; + +static void listPlugins() +{ + KInstance instance( "kontact" ); // Can't use KontactApp since it's too late for adding cmdline options + KTrader::OfferList offers = KTrader::self()->query( + QString::fromLatin1( "Kontact/Plugin" ), + QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) ); + for ( KService::List::Iterator it = offers.begin(); it != offers.end(); ++it ) { + KService::Ptr service = (*it); + // skip summary only plugins + QVariant var = service->property( "X-KDE-KontactPluginHasPart" ); + if ( var.isValid() && var.toBool() == false ) + continue; + cout << service->library().remove( "libkontact_" ).latin1() << endl; + } +} + +int KontactApp::newInstance() +{ + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + QString moduleName; + if ( Kontact::Prefs::self()->forceStartupPlugin() ) { + moduleName = Kontact::Prefs::self()->forcedStartupPlugin(); + } + if ( args->isSet( "module" ) ) { + moduleName = QString::fromLocal8Bit( args->getOption( "module" ) ); + } + + if ( !mSessionRestored ) { + if ( !mMainWindow ) { + mMainWindow = new Kontact::MainWindow(); + if ( !moduleName.isEmpty() ) + mMainWindow->setActivePluginModule( moduleName ); + mMainWindow->show(); + setMainWidget( mMainWindow ); + // --iconify is needed in kontact, although kstart can do that too, + // because kstart returns immediately so it's too early to talk DCOP to the app. + if ( args->isSet( "iconify" ) ) + KWin::iconifyWindow( mMainWindow->winId(), false /*no animation*/ ); + } else { + if ( !moduleName.isEmpty() ) + mMainWindow->setActivePluginModule( moduleName ); + } + } + + AlarmClient alarmclient; + alarmclient.startDaemon(); + + // Handle startup notification and window activation + // (The first time it will do nothing except note that it was called) + return KUniqueApplication::newInstance(); +} + +int main( int argc, char **argv ) +{ + KAboutData about( "kontact", I18N_NOOP( "Kontact" ), version, description, + KAboutData::License_GPL, I18N_NOOP("(C) 2001-2008 The Kontact developers"), 0, "http://kontact.org" ); + about.addAuthor( "Daniel Molkentin", 0, "molkentin@kde.org" ); + about.addAuthor( "Don Sanders", 0, "sanders@kde.org" ); + about.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" ); + about.addAuthor( "Tobias K\303\266nig", 0, "tokoe@kde.org" ); + about.addAuthor( "David Faure", 0, "faure@kde.org" ); + about.addAuthor( "Ingo Kl\303\266cker", 0, "kloecker@kde.org" ); + about.addAuthor( "Sven L\303\274ppken", 0, "sven@kde.org" ); + about.addAuthor( "Zack Rusin", 0, "zack@kde.org" ); + about.addAuthor( "Matthias Hoelzer-Kluepfel", I18N_NOOP("Original Author"), "mhk@kde.org" ); + + KCmdLineArgs::init( argc, argv, &about ); + Kontact::UniqueAppHandler::loadKontactCommandLineOptions(); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if ( args->isSet( "list" ) ) { + listPlugins(); + return 0; + } + + if ( !KontactApp::start() ) { + // Already running, brought to the foreground. + return 0; + } + + KontactApp app; + if ( app.restoringSession() ) { + // There can only be one main window + if ( KMainWindow::canBeRestored( 1 ) ) { + Kontact::MainWindow *mainWindow = new Kontact::MainWindow(); + app.setMainWindow( mainWindow ); + app.setSessionRestored( true ); + mainWindow->show(); + mainWindow->restore( 1 ); + } + } + + bool ret = app.exec(); + while ( KMainWindow::memberList->first() ) + delete KMainWindow::memberList->first(); + + return ret; +} diff --git a/kontact/src/mainwindow.cpp b/kontact/src/mainwindow.cpp new file mode 100644 index 000000000..de4eb2df7 --- /dev/null +++ b/kontact/src/mainwindow.cpp @@ -0,0 +1,1100 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + Copyright (c) 2002-2005 Daniel Molkentin <molkentin@kde.org> + Copyright (c) 2003-2005 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <qcombobox.h> +#include <qdockarea.h> +#include <qguardedptr.h> +#include <qhbox.h> +#include <qimage.h> +#include <qobjectlist.h> +#include <qprogressbar.h> +#include <qpushbutton.h> +#include <qsplitter.h> +#include <qtimer.h> +#include <qwhatsthis.h> + +#include <dcopclient.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kedittoolbar.h> +#include <kguiitem.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <kkeydialog.h> +#include <klibloader.h> +#include <klistbox.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kparts/componentfactory.h> +#include <kplugininfo.h> +#include <kpopupmenu.h> +#include <ksettings/dialog.h> +#include <ksettings/dispatcher.h> +#include <kshortcut.h> +#include <kstandarddirs.h> +#include <kstatusbar.h> +#include <kstdaction.h> +#include <ktip.h> +#include <ktrader.h> +#include <ksettings/componentsdialog.h> +#include <kstringhandler.h> +#include <krsqueezedtextlabel.h> +#include <khtml_part.h> +#include <khtmlview.h> +#include <libkdepim/kfileio.h> +#include <kcursor.h> +#include <krun.h> +#include <kaboutdata.h> +#include <kmenubar.h> +#include <kstdaccel.h> +#include <kcmultidialog.h> +#include <kipc.h> + +#include "aboutdialog.h" +#include "iconsidepane.h" +#include "mainwindow.h" +#include "plugin.h" +#include "prefs.h" +#include "profiledialog.h" +#include "profilemanager.h" +#include "progressdialog.h" +#include "statusbarprogresswidget.h" +#include "broadcaststatus.h" + +using namespace Kontact; + +class SettingsDialogWrapper : public KSettings::Dialog +{ + public: + SettingsDialogWrapper( ContentInListView content, QWidget * parent = 0 ) + : KSettings::Dialog( content, parent, 0 ) + { + } + + + void fixButtonLabel( QWidget *widget ) + { + QObject *object = widget->child( "KJanusWidget::buttonBelowList" ); + QPushButton *button = static_cast<QPushButton*>( object ); + if ( button ) + button->setText( i18n( "Select Components ..." ) ); + } +}; + +MainWindow::MainWindow() + : Kontact::Core(), mTopWidget( 0 ), mSplitter( 0 ), + mCurrentPlugin( 0 ), mAboutDialog( 0 ), mReallyClose( false ), mSyncActionsEnabled( true ) +{ + // Set this to be the group leader for all subdialogs - this means + // modal subdialogs will only affect this dialog, not the other windows + setWFlags( getWFlags() | WGroupLeader ); + + initGUI(); + initObject(); +} + +void MainWindow::initGUI() +{ + initWidgets(); + setupActions(); + setHelpMenuEnabled( false ); + KHelpMenu *helpMenu = new KHelpMenu( this, 0, true, actionCollection() ); + connect( helpMenu, SIGNAL( showAboutApplication() ), + SLOT( showAboutDialog() ) ); + + KStdAction::keyBindings( this, SLOT( configureShortcuts() ), actionCollection() ); + KStdAction::configureToolbars( this, SLOT( configureToolbars() ), actionCollection() ); + setXMLFile( "kontactui.rc" ); + + setStandardToolBarMenuEnabled( true ); + + createGUI( 0 ); + + resize( 700, 520 ); // initial size to prevent a scrollbar in sidepane + setAutoSaveSettings(); + + connect( Kontact::ProfileManager::self(), SIGNAL( profileLoaded( const QString& ) ), + this, SLOT( slotLoadProfile( const QString& ) ) ); + connect( Kontact::ProfileManager::self(), SIGNAL( saveToProfileRequested( const QString& ) ), + this, SLOT( slotSaveToProfile( const QString& ) ) ); +} + + +void MainWindow::initObject() +{ + KTrader::OfferList offers = KTrader::self()->query( + QString::fromLatin1( "Kontact/Plugin" ), + QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) ); + mPluginInfos = KPluginInfo::fromServices( offers, Prefs::self()->config(), "Plugins" ); + + KPluginInfo::List::Iterator it; + for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) { + ( *it )->load(); + } + + // prepare the part manager + mPartManager = new KParts::PartManager( this ); + connect( mPartManager, SIGNAL( activePartChanged( KParts::Part* ) ), + this, SLOT( slotActivePartChanged( KParts::Part* ) ) ); + + loadPlugins(); + + if ( mSidePane ) { + mSidePane->updatePlugins(); + plugActionList( "navigator_actionlist", mSidePane->actions() ); + } + + KSettings::Dispatcher::self()->registerInstance( instance(), this, + SLOT( updateConfig() ) ); + + loadSettings(); + + statusBar()->show(); + + showTip( false ); + + // done initializing + slotShowStatusMsg( QString::null ); + + connect( KPIM::BroadcastStatus::instance(), SIGNAL( statusMsg( const QString& ) ), + this, SLOT( slotShowStatusMsg( const QString& ) ) ); + + // launch commandline specified module if any + activatePluginModule(); + + if ( Prefs::lastVersionSeen() == kapp->aboutData()->version() ) { + selectPlugin( mCurrentPlugin ); + } + + paintAboutScreen( introductionString() ); + Prefs::setLastVersionSeen( kapp->aboutData()->version() ); +} + +MainWindow::~MainWindow() +{ + saveSettings(); + + QPtrList<KParts::Part> parts = *mPartManager->parts(); + + for ( KParts::Part *p = parts.last(); p; p = parts.prev() ) { + delete p; + p = 0; + } + + Prefs::self()->writeConfig(); +} + +void MainWindow::setActivePluginModule( const QString &module ) +{ + mActiveModule = module; + activatePluginModule(); +} + +void MainWindow::activatePluginModule() +{ + if ( !mActiveModule.isEmpty() ) { + PluginList::ConstIterator end = mPlugins.end(); + for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) + if ( ( *it )->identifier().contains( mActiveModule ) ) { + selectPlugin( *it ); + return; + } + } +} + +void MainWindow::initWidgets() +{ + // includes sidebar and part stack + mTopWidget = new QHBox( this ); + mTopWidget->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + setCentralWidget( mTopWidget ); + + QHBox *mBox = 0; + mSplitter = new QSplitter( mTopWidget ); + mBox = new QHBox( mTopWidget ); + mSidePane = new IconSidePane( this, mSplitter ); + mSidePane->setSizePolicy( QSizePolicy( QSizePolicy::Maximum, + QSizePolicy::Preferred ) ); + // donÄt occupy screen estate on load + QValueList<int> sizes; + sizes << 0; + mSplitter->setSizes(sizes); + + mSidePane->setActionCollection( actionCollection() ); + + connect( mSidePane, SIGNAL( pluginSelected( Kontact::Plugin * ) ), + SLOT( selectPlugin( Kontact::Plugin * ) ) ); + + QVBox *vBox; + if ( mSplitter ) { + vBox = new QVBox( mSplitter ); + } else { + vBox = new QVBox( mBox ); + } + + vBox->setSpacing( 0 ); + + mPartsStack = new QWidgetStack( vBox ); + initAboutScreen(); + + QString loading = i18n( "<h2 style='text-align:center; margin-top: 0px; margin-bottom: 0px'>%1</h2>" ) + .arg( i18n("Loading Kontact...") ); + + paintAboutScreen( loading ); + + /* Create a progress dialog and hide it. */ + KPIM::ProgressDialog *progressDialog = new KPIM::ProgressDialog( statusBar(), this ); + progressDialog->hide(); + + mLittleProgress = new KPIM::StatusbarProgressWidget( progressDialog, statusBar() ); + + mStatusMsgLabel = new KRSqueezedTextLabel( i18n( " Initializing..." ), statusBar() ); + mStatusMsgLabel->setAlignment( AlignLeft | AlignVCenter ); + + statusBar()->addWidget( mStatusMsgLabel, 10 , false ); + statusBar()->addWidget( mLittleProgress, 0 , true ); + mLittleProgress->show(); +} + + +void MainWindow::paintAboutScreen( const QString& msg ) +{ + QString location = locate( "data", "kontact/about/main.html" ); + QString content = KPIM::kFileToString( location ); + content = content.arg( locate( "data", "libkdepim/about/kde_infopage.css" ) ); + if ( kapp->reverseLayout() ) + content = content.arg( "@import \"%1\";" ).arg( locate( "data", "libkdepim/about/kde_infopage_rtl.css" ) ); + else + content = content.arg( "" ); + + mIntroPart->begin( KURL( location ) ); + + QString appName( i18n( "KDE Kontact" ) ); + QString catchPhrase( i18n( "Get Organized!" ) ); + QString quickDescription( i18n( "The KDE Personal Information Management Suite" ) ); + + mIntroPart->write( content.arg( QFont().pointSize() + 2 ).arg( appName ) + .arg( catchPhrase ).arg( quickDescription ).arg( msg ) ); + mIntroPart->end(); +} + +void MainWindow::initAboutScreen() +{ + QHBox *introbox = new QHBox( mPartsStack ); + mPartsStack->addWidget( introbox ); + mPartsStack->raiseWidget( introbox ); + mIntroPart = new KHTMLPart( introbox ); + mIntroPart->widget()->setFocusPolicy( WheelFocus ); + // Let's better be paranoid and disable plugins (it defaults to enabled): + mIntroPart->setPluginsEnabled( false ); + mIntroPart->setJScriptEnabled( false ); // just make this explicit + mIntroPart->setJavaEnabled( false ); // just make this explicit + mIntroPart->setMetaRefreshEnabled( false ); + mIntroPart->setURLCursor( KCursor::handCursor() ); + mIntroPart->view()->setLineWidth( 0 ); + + connect( mIntroPart->browserExtension(), + SIGNAL( openURLRequest( const KURL&, const KParts::URLArgs& ) ), + SLOT( slotOpenUrl( const KURL& ) ) ); + + connect( mIntroPart->browserExtension(), + SIGNAL( createNewWindow( const KURL&, const KParts::URLArgs& ) ), + SLOT( slotOpenUrl( const KURL& ) ) ); +} + +void MainWindow::setupActions() +{ + KStdAction::quit( this, SLOT( slotQuit() ), actionCollection() ); + mNewActions = new KToolBarPopupAction( KGuiItem( i18n( "New" ), "" ), + KStdAccel::shortcut(KStdAccel::New), this, SLOT( slotNewClicked() ), + actionCollection(), "action_new" ); + + KConfig* const cfg = Prefs::self()->config(); + cfg->setGroup( "Kontact Groupware Settings" ); + mSyncActionsEnabled = cfg->readBoolEntry( "GroupwareMailFoldersEnabled", true ); + + if ( mSyncActionsEnabled ) { + mSyncActions = new KToolBarPopupAction( KGuiItem( i18n( "Synchronize" ), "kitchensync" ), + KStdAccel::shortcut(KStdAccel::Reload), this, SLOT( slotSyncClicked() ), + actionCollection(), "action_sync" ); + } + new KAction( i18n( "Configure Kontact..." ), "configure", 0, this, SLOT( slotPreferences() ), + actionCollection(), "settings_configure_kontact" ); + + new KAction( i18n( "Configure &Profiles..." ), 0, this, SLOT( slotConfigureProfiles() ), + actionCollection(), "settings_configure_kontact_profiles" ); + + new KAction( i18n( "&Kontact Introduction" ), 0, this, SLOT( slotShowIntroduction() ), + actionCollection(), "help_introduction" ); + new KAction( i18n( "&Tip of the Day" ), 0, this, SLOT( slotShowTip() ), + actionCollection(), "help_tipofday" ); + new KAction( i18n( "&Request Feature..." ), 0, this, SLOT( slotRequestFeature() ), + actionCollection(), "help_requestfeature" ); + + KWidgetAction* spacerAction = new KWidgetAction( new QWidget( this ), "SpacerAction", "", 0, 0, actionCollection(), "navigator_spacer_item" ); + spacerAction->setAutoSized( true ); +} + +void MainWindow::slotConfigureProfiles() +{ + QGuardedPtr<Kontact::ProfileDialog> dlg = new Kontact::ProfileDialog( this ); + dlg->setModal( true ); + dlg->exec(); + delete dlg; +} + +namespace { + void copyConfigEntry( KConfig* source, KConfig* dest, const QString& group, const QString& key, const QString& defaultValue=QString() ) + { + source->setGroup( group ); + dest->setGroup( group ); + dest->writeEntry( key, source->readEntry( key, defaultValue ) ); + } +} + +void MainWindow::slotSaveToProfile( const QString& id ) +{ + const QString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation(); + if ( path.isNull() ) + return; + + KConfig* const cfg = Prefs::self()->config(); + Prefs::self()->writeConfig(); + saveMainWindowSettings( cfg ); + saveSettings(); + + KConfig profile( path+"/kontactrc", /*read-only=*/false, /*useglobals=*/false ); + ::copyConfigEntry( cfg, &profile, "MainWindow Toolbar navigatorToolBar", "Hidden", "true" ); + ::copyConfigEntry( cfg, &profile, "View", "SidePaneSplitter" ); + ::copyConfigEntry( cfg, &profile, "Icons", "Theme" ); + + for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) { + if ( !(*it)->isRunningStandalone() ) { + (*it)->part(); + } + (*it)->saveToProfile( path ); + } +} + +void MainWindow::slotLoadProfile( const QString& id ) +{ + const QString path = Kontact::ProfileManager::self()->profileById( id ).saveLocation(); + if ( path.isNull() ) + return; + + KConfig* const cfg = Prefs::self()->config(); + Prefs::self()->writeConfig(); + saveMainWindowSettings( cfg ); + saveSettings(); + + const KConfig profile( path+"/kontactrc", /*read-only=*/false, /*useglobals=*/false ); + const QStringList groups = profile.groupList(); + for ( QStringList::ConstIterator it = groups.begin(), end = groups.end(); it != end; ++it ) + { + cfg->setGroup( *it ); + typedef QMap<QString, QString> StringMap; + const StringMap entries = profile.entryMap( *it ); + for ( StringMap::ConstIterator it2 = entries.begin(), end = entries.end(); it2 != end; ++it2 ) + { + if ( it2.data() == "KONTACT_PROFILE_DELETE_KEY" ) + cfg->deleteEntry( it2.key() ); + else + cfg->writeEntry( it2.key(), it2.data() ); + } + } + + cfg->sync(); + Prefs::self()->readConfig(); + applyMainWindowSettings( cfg ); + KIconTheme::reconfigure(); + const WId wid = winId(); + KIPC::sendMessage( KIPC::PaletteChanged, wid ); + KIPC::sendMessage( KIPC::FontChanged, wid ); + KIPC::sendMessage( KIPC::StyleChanged, wid ); + KIPC::sendMessage( KIPC::SettingsChanged, wid ); + for ( int i = 0; i < KIcon::LastGroup; ++i ) + KIPC::sendMessage( KIPC::IconChanged, wid, i ); + + loadSettings(); + + for ( PluginList::Iterator it = mPlugins.begin(); it != mPlugins.end(); ++it ) { + if ( !(*it)->isRunningStandalone() ) { + kdDebug() << "Ensure loaded: " << (*it)->identifier() << endl; + (*it)->part(); + } + (*it)->loadProfile( path ); + } +} + +bool MainWindow::isPluginLoaded( const KPluginInfo *info ) +{ + return (pluginFromInfo( info ) != 0); +} + +Plugin *MainWindow::pluginFromInfo( const KPluginInfo *info ) +{ + PluginList::ConstIterator end = mPlugins.end(); + for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) + if ( (*it)->identifier() == info->pluginName() ) + return *it; + + return 0; +} + +void MainWindow::loadPlugins() +{ + QPtrList<Plugin> plugins; + QPtrList<KParts::Part> loadDelayed; + + uint i; + KPluginInfo::List::ConstIterator it; + for ( it = mPluginInfos.begin(); it != mPluginInfos.end(); ++it ) { + if ( !(*it)->isPluginEnabled() ) + continue; + if ( isPluginLoaded( *it ) ) { + Plugin *plugin = pluginFromInfo( *it ); + if ( plugin ) + plugin->configUpdated(); + continue; + } + + kdDebug(5600) << "Loading Plugin: " << (*it)->name() << endl; + Kontact::Plugin *plugin = + KParts::ComponentFactory::createInstanceFromService<Kontact::Plugin>( + (*it)->service(), this ); + + if ( !plugin ) + continue; + + plugin->setIdentifier( (*it)->pluginName() ); + plugin->setTitle( (*it)->name() ); + plugin->setIcon( (*it)->icon() ); + + QVariant libNameProp = (*it)->property( "X-KDE-KontactPartLibraryName" ); + QVariant exeNameProp = (*it)->property( "X-KDE-KontactPartExecutableName" ); + QVariant loadOnStart = (*it)->property( "X-KDE-KontactPartLoadOnStart" ); + QVariant hasPartProp = (*it)->property( "X-KDE-KontactPluginHasPart" ); + + if ( !loadOnStart.isNull() && loadOnStart.toBool() ) + mDelayedPreload.append( plugin ); + + kdDebug(5600) << "LIBNAMEPART: " << libNameProp.toString() << endl; + + plugin->setPartLibraryName( libNameProp.toString().utf8() ); + plugin->setExecutableName( exeNameProp.toString() ); + if ( hasPartProp.isValid() ) + plugin->setShowInSideBar( hasPartProp.toBool() ); + + for ( i = 0; i < plugins.count(); ++i ) { + Plugin *p = plugins.at( i ); + if ( plugin->weight() < p->weight() ) + break; + } + + plugins.insert( i, plugin ); + } + + for ( i = 0; i < plugins.count(); ++ i ) { + Plugin *plugin = plugins.at( i ); + + KAction *action; + QPtrList<KAction> *actionList = plugin->newActions(); + + for ( action = actionList->first(); action; action = actionList->next() ) { + kdDebug(5600) << "Plugging " << action->name() << endl; + action->plug( mNewActions->popupMenu() ); + } + + if ( mSyncActionsEnabled ) { + actionList = plugin->syncActions(); + for ( action = actionList->first(); action; action = actionList->next() ) { + kdDebug(5600) << "Plugging " << action->name() << endl; + action->plug( mSyncActions->popupMenu() ); + } + } + addPlugin( plugin ); + } + + mNewActions->setEnabled( mPlugins.size() != 0 ); + if ( mSyncActionsEnabled ) + mSyncActions->setEnabled( mPlugins.size() != 0 ); +} + +void MainWindow::unloadPlugins() +{ + KPluginInfo::List::ConstIterator end = mPluginInfos.end(); + KPluginInfo::List::ConstIterator it; + for ( it = mPluginInfos.begin(); it != end; ++it ) { + if ( !(*it)->isPluginEnabled() ) + removePlugin( *it ); + } +} + +bool MainWindow::removePlugin( const KPluginInfo *info ) +{ + PluginList::Iterator end = mPlugins.end(); + for ( PluginList::Iterator it = mPlugins.begin(); it != end; ++it ) + if ( ( *it )->identifier() == info->pluginName() ) { + Plugin *plugin = *it; + + KAction *action; + QPtrList<KAction> *actionList = plugin->newActions(); + + for ( action = actionList->first(); action; action = actionList->next() ) { + kdDebug(5600) << "Unplugging " << action->name() << endl; + action->unplug( mNewActions->popupMenu() ); + } + + if ( mSyncActionsEnabled ) { + actionList = plugin->syncActions(); + for ( action = actionList->first(); action; action = actionList->next() ) { + kdDebug(5600) << "Unplugging " << action->name() << endl; + action->unplug( mSyncActions->popupMenu() ); + } + } + removeChildClient( plugin ); + + if ( mCurrentPlugin == plugin ) + mCurrentPlugin = 0; + + delete plugin; // removes the part automatically + mPlugins.remove( it ); + + if ( mCurrentPlugin == 0 ) { + PluginList::Iterator it; + for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) { + if ( (*it)->showInSideBar() ) { + selectPlugin( *it ); + return true; + } + } + } + + return true; + } + + return false; +} + +void MainWindow::addPlugin( Kontact::Plugin *plugin ) +{ + kdDebug(5600) << "Added plugin" << endl; + + mPlugins.append( plugin ); + + // merge the plugins GUI into the main window + insertChildClient( plugin ); +} + +void MainWindow::partLoaded( Kontact::Plugin*, KParts::ReadOnlyPart *part ) +{ + // See if we have this part already (e.g. due to two plugins sharing it) + if ( mPartsStack->id( part->widget() ) != -1 ) + return; + + mPartsStack->addWidget( part->widget() ); + + mPartManager->addPart( part, false ); + // Workaround for KParts misbehavior: addPart calls show! + part->widget()->hide(); +} + +void MainWindow::slotActivePartChanged( KParts::Part *part ) +{ + if ( !part ) { + createGUI( 0 ); + return; + } + + kdDebug(5600) << "Part activated: " << part << " with stack id. " + << mPartsStack->id( part->widget() )<< endl; + + //createGUI( part ); // moved to selectPlugin() + + statusBar()->clear(); +} + +void MainWindow::slotNewClicked() +{ + KAction *action = mCurrentPlugin->newActions()->first(); + if ( action ) { + action->activate(); + } else { + PluginList::Iterator it; + for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) { + action = (*it)->newActions()->first(); + if ( action ) { + action->activate(); + return; + } + } + } +} + +void MainWindow::slotSyncClicked() +{ + KAction *action = mCurrentPlugin->syncActions()->first(); + if ( action ) { + action->activate(); + } else { + PluginList::Iterator it; + for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) { + action = (*it)->syncActions()->first(); + if ( action ) { + action->activate(); + return; + } + } + } +} + +KToolBar* Kontact::MainWindow::findToolBar(const char* name) +{ + // like KMainWindow::toolBar, but which doesn't create the toolbar if not found + return static_cast<KToolBar *>(child(name, "KToolBar")); +} + +void MainWindow::selectPlugin( Kontact::Plugin *plugin ) +{ + if ( !plugin ) + return; + + if ( plugin->isRunningStandalone() ) { + statusBar()->message( i18n( "Application is running standalone. Foregrounding..." ), 1000 ); + mSidePane->indicateForegrunding( plugin ); + plugin->bringToForeground(); + return; + } + + KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) ); + + KParts::Part *part = plugin->part(); + + if ( !part ) { + KApplication::restoreOverrideCursor(); + KMessageBox::error( this, i18n( "Cannot load part for %1." ) + .arg( plugin->title() ) + + "\n" + lastErrorMessage() ); + plugin->setDisabled( true ); + mSidePane->updatePlugins(); + return; + } + + // store old focus widget + QWidget *focusWidget = kapp->focusWidget(); + if ( mCurrentPlugin && focusWidget ) { + // save the focus widget only when it belongs to the activated part + QWidget *parent = focusWidget->parentWidget(); + while ( parent ) { + if ( parent == mCurrentPlugin->part()->widget() ) + mFocusWidgets.insert( mCurrentPlugin->identifier(), QGuardedPtr<QWidget>( focusWidget ) ); + + parent = parent->parentWidget(); + } + } + + if ( mSidePane ) + mSidePane->selectPlugin( plugin ); + + plugin->select(); + + mPartManager->setActivePart( part ); + QWidget *view = part->widget(); + Q_ASSERT( view ); + + if ( view ) { + mPartsStack->raiseWidget( view ); + view->show(); + + if ( mFocusWidgets.contains( plugin->identifier() ) ) { + focusWidget = mFocusWidgets[ plugin->identifier() ]; + if ( focusWidget ) + focusWidget->setFocus(); + } else + view->setFocus(); + + mCurrentPlugin = plugin; + KAction *newAction = plugin->newActions()->first(); + KAction *syncAction = plugin->syncActions()->first(); + + createGUI( plugin->part() ); + + KToolBar* navigatorToolBar = findToolBar( "navigatorToolBar" ); + // Let the navigator toolbar be always the last one, if it's in the top dockwindow + if ( navigatorToolBar && !navigatorToolBar->isHidden() && + navigatorToolBar->barPos() == KToolBar::Top ) { + topDock()->moveDockWindow( navigatorToolBar, -1 ); + } + + setCaption( i18n( "Plugin dependent window title" ,"%1 - Kontact" ).arg( plugin->title() ) ); + + if ( newAction ) { + mNewActions->setIcon( newAction->icon() ); + mNewActions->setText( newAction->text() ); + } else { // we'll use the action of the first plugin which offers one + PluginList::Iterator it; + for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) { + newAction = (*it)->newActions()->first(); + if ( newAction ) { + mNewActions->setIcon( newAction->icon() ); + mNewActions->setText( newAction->text() ); + break; + } + } + } + if ( mSyncActionsEnabled ) { + if ( syncAction ) { + mSyncActions->setIcon( syncAction->icon() ); + mSyncActions->setText( syncAction->text() ); + } else { // we'll use the action of the first plugin which offers one + PluginList::Iterator it; + for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) { + syncAction = (*it)->syncActions()->first(); + if ( syncAction ) { + mSyncActions->setIcon( syncAction->icon() ); + mSyncActions->setText( syncAction->text() ); + break; + } + } + } + } + } + QStringList invisibleActions = plugin->invisibleToolbarActions(); + + QStringList::ConstIterator it; + for ( it = invisibleActions.begin(); it != invisibleActions.end(); ++it ) { + KAction *action = part->actionCollection()->action( (*it).latin1() ); + if ( action ) { + QPtrListIterator<KToolBar> it( toolBarIterator() ); + for ( ; it.current() ; ++it ) { + action->unplug( it.current() ); + } + } + } + + KApplication::restoreOverrideCursor(); +} + +void MainWindow::selectPlugin( const QString &pluginName ) +{ + PluginList::ConstIterator end = mPlugins.end(); + for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) + if ( ( *it )->identifier() == pluginName ) { + selectPlugin( *it ); + return; + } +} + +void MainWindow::loadSettings() +{ + if ( mSplitter ) + mSplitter->setSizes( Prefs::self()->mSidePaneSplitter ); + + // Preload Plugins. This _must_ happen before the default part is loaded + PluginList::ConstIterator it; + for ( it = mDelayedPreload.begin(); it != mDelayedPreload.end(); ++it ) + selectPlugin( *it ); + + selectPlugin( Prefs::self()->mActivePlugin ); +} + +void MainWindow::saveSettings() +{ + if ( mSplitter ) + Prefs::self()->mSidePaneSplitter = mSplitter->sizes(); + + if ( mCurrentPlugin ) + Prefs::self()->mActivePlugin = mCurrentPlugin->identifier(); +} + +void MainWindow::slotShowTip() +{ + showTip( true ); +} + +void MainWindow::slotRequestFeature() +{ + if ( kapp ) + kapp->invokeBrowser( "http://kontact.org/shopping" ); +} + +void MainWindow::slotShowIntroduction() +{ + mPartsStack->raiseWidget( 0 ); // ### +} + +void MainWindow::showTip( bool force ) +{ + QStringList tips; + PluginList::ConstIterator end = mPlugins.end(); + for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) { + QString file = (*it)->tipFile(); + if ( !file.isEmpty() ) + tips.append( file ); + } + + KTipDialog::showMultiTip( this, tips, force ); +} + +void MainWindow::slotQuit() +{ + mReallyClose = true; + close(); +} + +void MainWindow::slotPreferences() +{ + static SettingsDialogWrapper *dlg = 0; + if ( !dlg ) { + // do not show settings of components running standalone + QValueList<KPluginInfo*> filteredPlugins = mPluginInfos; + PluginList::ConstIterator it; + for ( it = mPlugins.begin(); it != mPlugins.end(); ++it ) + if ( (*it)->isRunningStandalone() ) { + QValueList<KPluginInfo*>::ConstIterator infoIt; + for ( infoIt = filteredPlugins.begin(); infoIt != filteredPlugins.end(); ++infoIt ) { + if ( (*infoIt)->pluginName() == (*it)->identifier() ) { + filteredPlugins.remove( *infoIt ); + break; + } + } + } + dlg = new SettingsDialogWrapper( KSettings::Dialog::Configurable, this ); + dlg->addPluginInfos( filteredPlugins ); + connect( dlg, SIGNAL( pluginSelectionChanged() ), + SLOT( pluginsChanged() ) ); + } + + dlg->show(); + dlg->fixButtonLabel( this ); +} + +int MainWindow::startServiceFor( const QString& serviceType, + const QString& constraint, + const QString& preferences, + QString *error, QCString* dcopService, + int flags ) +{ + PluginList::ConstIterator end = mPlugins.end(); + for ( PluginList::ConstIterator it = mPlugins.begin(); it != end; ++it ) { + if ( (*it)->createDCOPInterface( serviceType ) ) { + kdDebug(5600) << "found interface for " << serviceType << endl; + if ( dcopService ) + *dcopService = (*it)->dcopClient()->appId(); + kdDebug(5600) << "appId=" << (*it)->dcopClient()->appId() << endl; + return 0; // success + } + } + + kdDebug(5600) << + "Didn't find dcop interface, falling back to external process" << endl; + + return KDCOPServiceStarter::startServiceFor( serviceType, constraint, + preferences, error, dcopService, flags ); +} + +void MainWindow::pluginsChanged() +{ + unplugActionList( "navigator_actionlist" ); + unloadPlugins(); + loadPlugins(); + mSidePane->updatePlugins(); + plugActionList( "navigator_actionlist", mSidePane->actions() ); +} + +void MainWindow::updateConfig() +{ + kdDebug( 5600 ) << k_funcinfo << endl; + + saveSettings(); + loadSettings(); +} + +void MainWindow::showAboutDialog() +{ + KApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) ); + + if ( !mAboutDialog ) + mAboutDialog = new AboutDialog( this ); + + mAboutDialog->show(); + mAboutDialog->raise(); + KApplication::restoreOverrideCursor(); +} + +void MainWindow::configureShortcuts() +{ + KKeyDialog dialog( true, this ); + dialog.insert( actionCollection() ); + + if ( mCurrentPlugin && mCurrentPlugin->part() ) + dialog.insert( mCurrentPlugin->part()->actionCollection() ); + + dialog.configure(); +} + +void MainWindow::configureToolbars() +{ + saveMainWindowSettings( KGlobal::config(), "MainWindow" ); + + KEditToolbar edit( factory() ); + connect( &edit, SIGNAL( newToolbarConfig() ), + this, SLOT( slotNewToolbarConfig() ) ); + edit.exec(); +} + +void MainWindow::slotNewToolbarConfig() +{ + if ( mCurrentPlugin && mCurrentPlugin->part() ) + createGUI( mCurrentPlugin->part() ); + applyMainWindowSettings( KGlobal::config(), "MainWindow" ); +} + +void MainWindow::slotOpenUrl( const KURL &url ) +{ + if ( url.protocol() == "exec" ) { + if ( url.path() == "/switch" ) { + selectPlugin( mCurrentPlugin ); + } + if ( url.path() == "/gwwizard" ) { + KRun::runCommand( "groupwarewizard" ); + slotQuit(); + } + } else + new KRun( url, this ); +} + +void MainWindow::readProperties( KConfig *config ) +{ + Core::readProperties( config ); + + QStringList activePlugins = config->readListEntry( "ActivePlugins" ); + QValueList<Plugin*>::ConstIterator it = mPlugins.begin(); + QValueList<Plugin*>::ConstIterator end = mPlugins.end(); + for ( ; it != end; ++it ) { + Plugin *plugin = *it; + if ( !plugin->isRunningStandalone() ) { + QStringList::ConstIterator activePlugin = activePlugins.find( plugin->identifier() ); + if ( activePlugin != activePlugins.end() ) { + plugin->readProperties( config ); + } + } + } +} + +void MainWindow::saveProperties( KConfig *config ) +{ + Core::saveProperties( config ); + + QStringList activePlugins; + + KPluginInfo::List::Iterator it = mPluginInfos.begin(); + KPluginInfo::List::Iterator end = mPluginInfos.end(); + for ( ; it != end; ++it ) { + KPluginInfo *info = *it; + if ( info->isPluginEnabled() ) { + Plugin *plugin = pluginFromInfo( info ); + if ( plugin ) { + activePlugins.append( plugin->identifier() ); + plugin->saveProperties( config ); + } + } + } + + config->writeEntry( "ActivePlugins", activePlugins ); +} + +bool MainWindow::queryClose() +{ + if ( kapp->sessionSaving() || mReallyClose ) + return true; + + bool localClose = true; + QValueList<Plugin*>::ConstIterator end = mPlugins.end(); + QValueList<Plugin*>::ConstIterator it = mPlugins.begin(); + for ( ; it != end; ++it ) { + Plugin *plugin = *it; + if ( !plugin->isRunningStandalone() ) + if ( !plugin->queryClose() ) + localClose = false; + } + + return localClose; +} + +void MainWindow::slotShowStatusMsg( const QString &msg ) +{ + if ( !statusBar() || !mStatusMsgLabel ) + return; + + mStatusMsgLabel->setText( msg ); +} + +QString MainWindow::introductionString() +{ + KIconLoader *iconloader = KGlobal::iconLoader(); + int iconSize = iconloader->currentSize( KIcon::Desktop ); + + QString handbook_icon_path = iconloader->iconPath( "contents2", KIcon::Desktop ); + QString html_icon_path = iconloader->iconPath( "html", KIcon::Desktop ); + QString wizard_icon_path = iconloader->iconPath( "wizard", KIcon::Desktop ); + + QString info = i18n( "<h2 style='text-align:center; margin-top: 0px;'>Welcome to Kontact %1</h2>" + "<p>%1</p>" + "<table align=\"center\">" + "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>" + "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>" + "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>" + "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>" + "<tr><td><a href=\"%1\"><img width=\"%1\" height=\"%1\" src=\"%1\" /></a></td>" + "<td><a href=\"%1\">%1</a><br><span id=\"subtext\"><nobr>%1</td></tr>" + "</table>" + "<p style=\"margin-bottom: 0px\"> <a href=\"%1\">Skip this introduction</a></p>" ) + .arg( kapp->aboutData()->version() ) + .arg( i18n( "Kontact handles your e-mail, addressbook, calendar, to-do list and more." ) ) + .arg( "help:/kontact" ) + .arg( iconSize ) + .arg( iconSize ) + .arg( handbook_icon_path ) + .arg( "help:/kontact" ) + .arg( i18n( "Read Manual" ) ) + .arg( i18n( "Learn more about Kontact and its components" ) ) + .arg( "http://kontact.org" ) + .arg( iconSize ) + .arg( iconSize ) + .arg( html_icon_path ) + .arg( "http://kontact.org" ) + .arg( i18n( "Visit Kontact Website" ) ) + .arg( i18n( "Access online resources and tutorials" ) ) + .arg( "exec:/gwwizard" ) + .arg( iconSize ) + .arg( iconSize ) + .arg( wizard_icon_path ) + .arg( "exec:/gwwizard" ) + .arg( i18n( "Configure Kontact as Groupware Client" ) ) + .arg( i18n( "Prepare Kontact for use in corporate networks" ) ) + .arg( "exec:/switch" ); + return info; +} + +#include "mainwindow.moc" diff --git a/kontact/src/mainwindow.h b/kontact/src/mainwindow.h new file mode 100644 index 000000000..a96d5bf6b --- /dev/null +++ b/kontact/src/mainwindow.h @@ -0,0 +1,168 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org> + Copyright (c) 2002-2005 Daniel Molkentin <molkentin@kde.org> + Copyright (c) 2003-2005 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +#ifndef KONTACT_MAINWINDOW_H +#define KONTACT_MAINWINDOW_H + +#include <qguardedptr.h> +#include <qptrlist.h> +#include <qwidgetstack.h> + +#include <kparts/mainwindow.h> +#include <kparts/part.h> +#include <kparts/partmanager.h> +#include <kdcopservicestarter.h> + +#include "core.h" +#include "kontactiface.h" + +class QHBox; +class QSplitter; +class QVBox; +class QFrame; + +class KAction; +class KConfig; +class KPluginInfo; +class KRSqueezedTextLabel; +class KHTMLPart; +class KeyPressEater; + +namespace KPIM +{ + class StatusbarProgressWidget; +} + +namespace Kontact +{ + +class Plugin; +class SidePaneBase; +class AboutDialog; + +typedef QValueList<Kontact::Plugin*> PluginList; + +class MainWindow : public Kontact::Core, public KDCOPServiceStarter, public KontactIface +{ + Q_OBJECT + + public: + MainWindow(); + ~MainWindow(); + + // KDCOPServiceStarter interface + virtual int startServiceFor( const QString& serviceType, + const QString& constraint = QString::null, + const QString& preferences = QString::null, + QString *error = 0, QCString* dcopService = 0, + int flags = 0 ); + + virtual PluginList pluginList() const { return mPlugins; } + void setActivePluginModule( const QString & ); + + public slots: + virtual void selectPlugin( Kontact::Plugin *plugin ); + virtual void selectPlugin( const QString &pluginName ); + + void updateConfig(); + + protected slots: + void initObject(); + void initGUI(); + void slotActivePartChanged( KParts::Part *part ); + void slotPreferences(); + void slotNewClicked(); + void slotSyncClicked(); + void slotQuit(); + void slotShowTip(); + void slotRequestFeature(); + void slotConfigureProfiles(); + void slotLoadProfile( const QString& id ); + void slotSaveToProfile( const QString& id ); + void slotNewToolbarConfig(); + void slotShowIntroduction(); + void showAboutDialog(); + void slotShowStatusMsg( const QString& ); + void activatePluginModule(); + void slotOpenUrl( const KURL &url ); + + private: + void initWidgets(); + void initAboutScreen(); + void loadSettings(); + void saveSettings(); + + bool isPluginLoaded( const KPluginInfo * ); + Kontact::Plugin *pluginFromInfo( const KPluginInfo * ); + void loadPlugins(); + void unloadPlugins(); + bool removePlugin( const KPluginInfo * ); + void addPlugin( Kontact::Plugin *plugin ); + void partLoaded( Kontact::Plugin *plugin, KParts::ReadOnlyPart *part ); + void setupActions(); + void showTip( bool ); + virtual bool queryClose(); + virtual void readProperties( KConfig *config ); + virtual void saveProperties( KConfig *config ); + void paintAboutScreen( const QString& msg ); + static QString introductionString(); + KToolBar* findToolBar(const char* name); + + private slots: + void pluginsChanged(); + + void configureShortcuts(); + void configureToolbars(); + + private: + QFrame *mTopWidget; + + QSplitter *mSplitter; + + KToolBarPopupAction *mNewActions; + KToolBarPopupAction *mSyncActions; + SidePaneBase *mSidePane; + QWidgetStack *mPartsStack; + Plugin *mCurrentPlugin; + KParts::PartManager *mPartManager; + PluginList mPlugins; + PluginList mDelayedPreload; + QValueList<KPluginInfo*> mPluginInfos; + KHTMLPart *mIntroPart; + + KRSqueezedTextLabel* mStatusMsgLabel; + KPIM::StatusbarProgressWidget *mLittleProgress; + + QString mActiveModule; + + QMap<QString, QGuardedPtr<QWidget> > mFocusWidgets; + + AboutDialog *mAboutDialog; + bool mReallyClose; + bool mSyncActionsEnabled; +}; + +} + +#endif +// vim: sw=2 sts=2 et diff --git a/kontact/src/prefs.kcfgc b/kontact/src/prefs.kcfgc new file mode 100644 index 000000000..0c200c592 --- /dev/null +++ b/kontact/src/prefs.kcfgc @@ -0,0 +1,13 @@ +# Code generation options for kconfig_compiler +File=kontact.kcfg +NameSpace=Kontact +ClassName=Prefs +Singleton=true +Mutators=true +#Inherits=KPimPrefs +#IncludeFiles=libkdepim/kpimprefs.h +Visibility=KDE_EXPORT +MemberVariables=public +GlobalEnums=true +ItemAccessors=true +SetUserTexts=true diff --git a/kontact/src/profiledialog.cpp b/kontact/src/profiledialog.cpp new file mode 100644 index 000000000..9525c968a --- /dev/null +++ b/kontact/src/profiledialog.cpp @@ -0,0 +1,267 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include "profiledialog.h" +#include "profilemanager.h" + +#include <kfiledialog.h> +#include <klistview.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include <qlayout.h> +#include <qpushbutton.h> +#include <qstring.h> + +Kontact::ProfileDialog::ProfileDialog( QWidget* parent, WFlags flags ) : KDialogBase( parent, /*name=*/0, /*modal=*/true, /*caption=*/QString(), /*buttonMask=*/KDialogBase::Ok|KDialogBase::Close ) +{ + setWFlags( flags ); + setCaption( i18n("Configure Profiles") ); + setButtonOK( i18n("Load Profile") ); + + QWidget* mainWidget = new QWidget( this ); + + QHBoxLayout* horizontalLayout = new QHBoxLayout( mainWidget ); + horizontalLayout->setSpacing( 5 ); + + m_list = new KListView( mainWidget ); + m_list->addColumn( i18n("Name") ); + m_list->addColumn( i18n("Description") ); + m_list->setSelectionMode( QListView::Single ); + m_list->setItemsRenameable( true ); + m_list->setRenameable( NameColumn, true ); + m_list->setRenameable( DescriptionColumn, true ); + + connect( m_list, SIGNAL( selectionChanged() ), + this, SLOT( listSelectionChanged() ) ); + connect( m_list, SIGNAL( itemRenamed( QListViewItem*, const QString&, int ) ), + this, SLOT( listItemRenamed( QListViewItem*, const QString&, int ) ) ); + horizontalLayout->addWidget( m_list ); + + QVBoxLayout* buttonLayout = new QVBoxLayout( horizontalLayout ); + buttonLayout->setSpacing( 5 ); + + m_newProfileButton = new QPushButton( mainWidget ); + m_newProfileButton->setText( i18n("New Profile") ); + connect( m_newProfileButton, SIGNAL( clicked() ), + this, SLOT( addNewProfile() ) ); + buttonLayout->addWidget( m_newProfileButton ); + + m_deleteProfileButton = new QPushButton( mainWidget ); + m_deleteProfileButton->setText( i18n("Delete Profile") ); + m_deleteProfileButton->setEnabled( false ); + connect( m_deleteProfileButton, SIGNAL( clicked() ), + this, SLOT( deleteSelectedProfile() ) ); + buttonLayout->addWidget( m_deleteProfileButton ); + + m_saveProfileButton = new QPushButton( mainWidget ); + m_saveProfileButton->setText( i18n("Save Profile") ); + m_saveProfileButton->setEnabled( false ); + connect( m_saveProfileButton, SIGNAL( clicked() ), + this, SLOT( saveToSelectedProfile() ) ); + buttonLayout->addWidget( m_saveProfileButton ); + + buttonLayout->addStretch(); + + m_importProfileButton = new QPushButton( mainWidget ); + m_importProfileButton->setText( i18n("Import Profile") ); + connect( m_importProfileButton, SIGNAL( clicked() ), + this, SLOT( importProfile() ) ); + buttonLayout->addWidget( m_importProfileButton ); + + m_exportProfileButton = new QPushButton( mainWidget ); + m_exportProfileButton->setText( i18n("Export Profile") ); + m_exportProfileButton->setEnabled( false ); + connect( m_exportProfileButton, SIGNAL( clicked() ), + this, SLOT( exportSelectedProfile() ) ); + buttonLayout->addWidget( m_exportProfileButton ); + + setMainWidget( mainWidget ); + + connect( Kontact::ProfileManager::self(), SIGNAL( profileAdded( const QString& ) ), + this, SLOT( profileAdded( const QString& ) ) ); + connect( Kontact::ProfileManager::self(), SIGNAL( profileRemoved( const QString& ) ), + this, SLOT( profileRemoved( const QString& ) ) ); + connect( Kontact::ProfileManager::self(), SIGNAL( profileLoaded( const QString& ) ), + this, SLOT( profileLoaded( const QString& ) ) ); + connect( Kontact::ProfileManager::self(), SIGNAL( profileUpdated( const QString& ) ), + this, SLOT( profileUpdated( const QString& ) ) ); + + const QValueList<Kontact::Profile> profiles = Kontact::ProfileManager::self()->profiles(); + for ( QValueList<Kontact::Profile>::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it ) + { + profileAdded( (*it).id() ); + } + updateButtonState(); +} + +void Kontact::ProfileDialog::slotOk() +{ + loadSelectedProfile(); + KDialogBase::slotOk(); +} + +QString Kontact::ProfileDialog::selectedProfile() const +{ + return m_itemToProfile[m_list->selectedItem()]; +} + +void Kontact::ProfileDialog::loadSelectedProfile() +{ + const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( selectedProfile() ); + if ( profile.isNull() ) + return; + Kontact::ProfileManager::self()->loadProfile( profile.id() ); +} + +void Kontact::ProfileDialog::profileLoaded( const QString& id ) +{ + const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id ); + if ( profile.isNull() ) + return; + KMessageBox::information( this, i18n("The profile \"%1\" was successfully loaded. Some profile settings require a restart to get activated.").arg( profile.name() ), i18n("Profile Loaded") ); +} + +void Kontact::ProfileDialog::saveToSelectedProfile() +{ + const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( selectedProfile() ); + if ( profile.isNull() ) + return; + if ( KMessageBox::Yes != KMessageBox::warningYesNo( this, i18n("The profile \"%1\" will be overwritten with the current settings. Are you sure?").arg( profile.name() ), i18n("Save to Profile"), KStdGuiItem::overwrite(), KStdGuiItem::cancel() ) ) + return; + Kontact::ProfileManager::self()->saveToProfile( profile.id() ); +} + +void Kontact::ProfileDialog::deleteSelectedProfile() +{ + const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( selectedProfile() ); + if ( profile.isNull() ) + return; + if ( KMessageBox::Yes != KMessageBox::warningYesNo( this, i18n("Do you really want to delete the profile \"%1\"? All profile settings will be lost!").arg( profile.name() ), i18n("Delete Profile"), KStdGuiItem::del(), KStdGuiItem::cancel() ) ) + return; + Kontact::ProfileManager::self()->removeProfile( profile ); +} + +void Kontact::ProfileDialog::exportSelectedProfile() +{ + const QString id = selectedProfile(); + const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id ); + if ( profile.isNull() ) + return; + const QString path = KFileDialog::getExistingDirectory( QString(), this, i18n("Select Profile Folder") ); + if ( path.isNull() ) + return; + const Kontact::ProfileManager::ExportError error = Kontact::ProfileManager::self()->exportProfileToDirectory( id, path ); + if ( error == Kontact::ProfileManager::SuccessfulExport ) + { + KMessageBox::information( this, i18n("The profile \"%1\" was successfully exported.").arg( profile.name() ), i18n("Profile Exported") ); + } + else + { + // TODO print error + } +} + +void Kontact::ProfileDialog::importProfile() +{ + const QString path = KFileDialog::getExistingDirectory( QString(), this, i18n("Select Profile Folder") ); + if ( path.isNull() ) + return; + const Kontact::ProfileManager::ImportError error = Kontact::ProfileManager::self()->importProfileFromDirectory( path ); + if ( error != Kontact::ProfileManager::SuccessfulImport ) + { + // TODO print error + } +} + +void Kontact::ProfileDialog::profileAdded( const QString& id ) +{ + Q_ASSERT( !m_profileToItem[id] ); + const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id ); + Q_ASSERT( !profile.isNull() ); + QListViewItem* const item = new QListViewItem( m_list ); + m_profileToItem[id] = item; + m_itemToProfile[item] = id; + profileUpdated( id ); +} + +void Kontact::ProfileDialog::profileRemoved( const QString& id ) +{ + QListViewItem* item = m_profileToItem[id]; + Q_ASSERT( item ); + m_profileToItem.remove( id ); + m_itemToProfile.remove( item ); + delete item; +} + +void Kontact::ProfileDialog::profileUpdated( const QString& id ) +{ + QListViewItem* item = m_profileToItem[id]; + Q_ASSERT( item ); + const Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( id ); + Q_ASSERT( !profile.isNull() ); + item->setText( NameColumn, profile.name() ); + item->setText( DescriptionColumn, profile.description() ); +} + +void Kontact::ProfileDialog::addNewProfile() +{ + Kontact::Profile profile( Kontact::ProfileManager::self()->generateNewId(), true ); + profile.setName( i18n("New profile") ); + profile.setDescription( i18n("Enter description") ); + Kontact::ProfileManager::self()->addProfile( profile ); +} + +void Kontact::ProfileDialog::listItemRenamed( QListViewItem* item, const QString& text, int col ) +{ + Kontact::Profile profile = Kontact::ProfileManager::self()->profileById( m_itemToProfile[item] ); + Q_ASSERT( !profile.isNull() ); + switch ( col ) + { + case NameColumn: + profile.setName( text ); + Kontact::ProfileManager::self()->updateProfile( profile ); + break; + case DescriptionColumn: + profile.setDescription( text ); + Kontact::ProfileManager::self()->updateProfile( profile ); + break; + } +} + +void Kontact::ProfileDialog::updateButtonState() +{ + const bool hasSelection = m_list->selectedItem() != 0; + m_deleteProfileButton->setEnabled( hasSelection ); + m_saveProfileButton->setEnabled( hasSelection); + actionButton( KDialogBase::Ok )->setEnabled( hasSelection ); + m_exportProfileButton->setEnabled( hasSelection ); +} + +void Kontact::ProfileDialog::listSelectionChanged() +{ + updateButtonState(); +} + +#include "profiledialog.moc" diff --git a/kontact/src/profiledialog.h b/kontact/src/profiledialog.h new file mode 100644 index 000000000..7fa620e6e --- /dev/null +++ b/kontact/src/profiledialog.h @@ -0,0 +1,90 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KONTACT_PROFILEDIALOG_H +#define KONTACT_PROFILEDIALOG_H + +#include <kdialogbase.h> + +#include <qmap.h> +#include <qstring.h> + +class QListViewItem; + +class KListView; +class QPushButton; + +namespace Kontact { + +class ProfileDialog : public KDialogBase +{ +Q_OBJECT + +public: + explicit ProfileDialog( QWidget* parent = 0, WFlags f = 0 ); + +private: + enum ListColumn { + NameColumn=0, + DescriptionColumn=1 + }; + + QString selectedProfile() const; + void updateButtonState(); + +protected slots: + + //override + void slotOk(); + +private slots: + + void loadSelectedProfile(); + void saveToSelectedProfile(); + void deleteSelectedProfile(); + void importProfile(); + void exportSelectedProfile(); + void addNewProfile(); + void listSelectionChanged(); + void listItemRenamed( QListViewItem* item, const QString& text, int col ); + + void profileAdded( const QString& id ); + void profileRemoved( const QString& id ); + void profileUpdated( const QString& id ); + void profileLoaded( const QString& id ); + +private: + KListView* m_list; + QPushButton* m_newProfileButton; + QPushButton* m_deleteProfileButton; + QPushButton* m_saveProfileButton; + QPushButton* m_importProfileButton; + QPushButton* m_exportProfileButton; + QMap<QListViewItem*, QString> m_itemToProfile; + QMap<QString, QListViewItem*> m_profileToItem; +}; + +} // Kontact + +#endif // KONTACT_PROFILEDIALOG_H diff --git a/kontact/src/profilemanager.cpp b/kontact/src/profilemanager.cpp new file mode 100644 index 000000000..53419cc54 --- /dev/null +++ b/kontact/src/profilemanager.cpp @@ -0,0 +1,340 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include "profilemanager.h" + +#include <kio/job.h> + +#include <kapplication.h> +#include <kconfig.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <kstaticdeleter.h> +#include <kurl.h> + +#include <qdir.h> +#include <qstringlist.h> +#include <qvaluelist.h> + +Kontact::Profile::Profile( const QString& id, bool isLocal ) : m_id( id ), m_local( isLocal ) +{ +} + +Kontact::Profile::Profile() : m_local( false ) +{ +} + +QString Kontact::Profile::id() const +{ + return m_id; +} + +QString Kontact::Profile::name() const +{ + return m_name; +} + +QString Kontact::Profile::description() const +{ + return m_description; +} + +bool Kontact::Profile::isNull() const +{ + return m_id.isNull(); +} + +void Kontact::Profile::setId( const QString& id ) +{ + m_id = id; +} + +void Kontact::Profile::setDescription( const QString& description ) +{ + m_description = description; +} + +void Kontact::Profile::setName( const QString& name ) +{ + m_name = name; +} + +void Kontact::Profile::setLocal( SetLocalMode mode ) +{ + if ( m_local ) + return; + + if ( mode == CopyProfileFiles ) + copyConfigFiles( m_originalLocation, localSaveLocation() ); + + m_local = true; +} + +bool Kontact::Profile::isLocal() const +{ + return m_local; +} + +void Kontact::Profile::setOriginalLocation( const QString& path ) +{ + m_originalLocation = path; +} + +QString Kontact::Profile::localSaveLocation() const +{ + + return m_id.isNull() ? QString() : locateLocal( "data", "kontact/profiles/" + m_id, /*create folder=*/true ); +} + +QString Kontact::Profile::saveLocation() const +{ + return m_local ? localSaveLocation() : m_originalLocation; +} + +bool Kontact::Profile::operator==( const Kontact::Profile& other ) const +{ + return m_id == other.m_id && m_name == other.m_name && m_description == other.m_description; +} + +Kontact::ProfileManager* Kontact::ProfileManager::m_self = 0; + +static KStaticDeleter<Kontact::ProfileManager> profileManagerSD; + +Kontact::ProfileManager* Kontact::ProfileManager::self() +{ + if ( m_self == 0 ) + { + profileManagerSD.setObject( m_self, new Kontact::ProfileManager ); + m_self->readConfig(); + } + return m_self; +} + +Kontact::ProfileManager::ProfileManager( QObject* parent ) : QObject( parent ) +{ +} + +Kontact::ProfileManager::~ProfileManager() +{ + writeConfig(); +} + +void Kontact::ProfileManager::writeConfig() const +{ + const QValueList<Kontact::Profile> profiles = m_profiles.values(); + for ( QValueList<Kontact::Profile>::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it ) + { + writeProfileConfig( *it ); + } +} + +Kontact::Profile Kontact::ProfileManager::readFromConfiguration( const QString& configFile, bool isLocal ) +{ + KConfig profileCfg( configFile, true /*read-only*/, false /*no KDE global*/ ); + const QString configDir = configFile.left( configFile.findRev( QDir::separator(), -1 ) ); + profileCfg.setGroup( "Kontact Profile" ); + const QString id = profileCfg.readEntry( "Identifier" ); + Kontact::Profile profile( id ); + profile.setName( profileCfg.readEntry( "Name" ) ); + profile.setDescription( profileCfg.readEntry( "Description" ) ); + profile.setOriginalLocation( configDir ); + if ( isLocal ) + profile.setLocal( Kontact::Profile::DoNotCopyProfileFiles ); + return profile; +} + +void Kontact::ProfileManager::writeProfileConfig( const Kontact::Profile& profile ) const +{ + const QString profileDir = profile.saveLocation(); + const QString cfgPath = profileDir + "/profile.cfg"; + KConfig profileCfg( cfgPath, false /*read-only*/, false /*no KDE global*/ ); + profileCfg.setGroup( "Kontact Profile" ); + profileCfg.writeEntry( "Identifier", profile.id() ); + profileCfg.writeEntry( "Name", profile.name() ); + profileCfg.writeEntry( "Description", profile.description() ); +} + +void Kontact::ProfileManager::readConfig() +{ + + const QStringList profilePaths = KGlobal::dirs()->findAllResources( "data", QString::fromLatin1( "kontact/profiles/*/profile.cfg" ) ); + + typedef QMap<QString, Kontact::Profile> ProfileMap; + ProfileMap profiles; + ProfileMap globalProfiles; + + const QString localPrefix = locateLocal( "data", "kontact/profiles/", /*createDir=*/false ); + for ( QStringList::ConstIterator it = profilePaths.begin(), end = profilePaths.end(); it != end; ++it ) + { + const bool isLocal = (*it).startsWith( localPrefix ); + const Kontact::Profile profile = readFromConfiguration( *it, isLocal ); + if ( profile.isNull() ) + continue; + if ( isLocal ) + profiles[profile.id()] = profile; + else + globalProfiles[profile.id()] = profile; + } + + for ( ProfileMap::ConstIterator it = globalProfiles.begin(), end = globalProfiles.end(); it != end; ++it ) + { + if ( !profiles.contains( it.key() ) ) + profiles[it.key()] = it.data(); + } + + for ( ProfileMap::ConstIterator it = profiles.begin(), end = profiles.end(); it != end; ++it ) + { + addProfile( *it, false /*dont sync config */ ); + } +} + +QValueList<Kontact::Profile> Kontact::ProfileManager::profiles() const +{ + return m_profiles.values(); +} + +Kontact::Profile Kontact::ProfileManager::profileById( const QString& id ) const +{ + return m_profiles[id]; +} + +void Kontact::ProfileManager::updateProfile( const Kontact::Profile& profile_ ) +{ + const QString id = profile_.id(); + if ( id.isNull() || m_profiles[id] == profile_ ) + return; + Kontact::Profile profile( profile_ ); + m_profiles[id] = profile; + profile.setLocal( Kontact::Profile::CopyProfileFiles ); + writeProfileConfig( profile ); + emit profileUpdated( id ); +} + +void Kontact::Profile::copyConfigFiles( const QString& source_, const QString& dest_ ) +{ + const KURL source = KURL::fromPathOrURL( source_+"/*rc" ); + const KURL dest = KURL::fromPathOrURL( dest_ ); + KIO::CopyJob* job = KIO::copy( source, dest, /*showProgressInfo=*/false ); + // TODO better check for the copy result +} + +void Kontact::ProfileManager::saveToProfile( const QString& id ) +{ + Kontact::Profile profile = profileById( id ); + if ( profile.isNull() ) + return; + profile.setLocal( Kontact::Profile::CopyProfileFiles ); + writeProfileConfig( profile ); + emit saveToProfileRequested( id ); +} + +bool Kontact::ProfileManager::addProfile( const Kontact::Profile& profile, bool syncConfig ) +{ + const QString id = profile.id(); + if ( m_profiles.contains( id ) ) + return false; + m_profiles[id] = profile; + emit profileAdded( id ); + emit saveToProfileRequested( id ); + if ( syncConfig ) { + writeProfileConfig( profile ); + } + + return true; +} + +void Kontact::ProfileManager::loadProfile( const QString& id ) +{ + if ( !m_profiles.contains( id ) ) + return; + emit profileLoaded( id ); +} + +void Kontact::ProfileManager::removeProfile( const Kontact::Profile& profile ) +{ + removeProfile( profile.id() ); +} + +void Kontact::ProfileManager::removeProfile( const QString& id ) +{ + if ( !m_profiles.contains( id ) ) + return; + Kontact::Profile profile = profileById( id ); + if ( profile.isLocal() ) { + KURL location = KURL::fromPathOrURL( profile.saveLocation() ); + KIO::DeleteJob* job = KIO::del( location, /*shred*/ false, /*showProgressInfo=*/false ); + // TODO check result + } + m_profiles.remove( id ); + emit profileRemoved( id ); + } + +Kontact::ProfileManager::ExportError Kontact::ProfileManager::exportProfileToDirectory( const QString& id, const QString& path ) +{ + if ( !m_profiles.contains( id ) ) + return SuccessfulExport; + + if ( !QDir( path ).exists() ) + return DirectoryDoesNotExist; + + const Kontact::Profile profile = profileById( id ); + const KURL source = KURL::fromPathOrURL( profile.saveLocation() ); + const KURL target = KURL::fromPathOrURL( path + QDir::separator() + profile.name() ); + + KIO::CopyJob* job = KIO::copy( source, target, /*showProgressInfo=*/false ); + // TODO check result + + return SuccessfulExport; +} + +Kontact::ProfileManager::ImportError Kontact::ProfileManager::importProfileFromDirectory( const QString& path ) +{ + Kontact::Profile profile = readFromConfiguration( path + "/profile.cfg", /*isLocal=*/ true ); + if ( profile.isNull() ) + return NoValidProfile; + + profile.setId( generateNewId() ); + + const KURL source = KURL::fromPathOrURL( path ); + const KURL target = KURL::fromPathOrURL( profile.saveLocation() ); + + KIO::CopyJob* job = KIO::copy( source, target, /*showProgressInfo=*/false ); + // TODO better check for the copy result + + addProfile( profile ); + + return SuccessfulImport; +} + +QString Kontact::ProfileManager::generateNewId() const +{ + while ( true ) + { + const QString newId = KApplication::randomString( 10 ); + if ( !m_profiles.contains( newId ) ) + return newId; + } +} + +#include "profilemanager.moc" diff --git a/kontact/src/profilemanager.h b/kontact/src/profilemanager.h new file mode 100644 index 000000000..e8b10adb5 --- /dev/null +++ b/kontact/src/profilemanager.h @@ -0,0 +1,162 @@ +/* + This file is part of KDE Kontact. + + Copyright (c) 2007 Frank Osterfeld <frank.osterfeld@kdemail.net> + + 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. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#ifndef KONTACT_PROFILEMANAGER_H +#define KONTACT_PROFILEMANAGER_H + +#include <qmap.h> +#include <qobject.h> +#include <qstring.h> + +template <class T> class QValueList; + +namespace KIO { + class Job; +} + +namespace Kontact { + +class Profile +{ + friend class ProfileManager; +public: + Profile(); + + explicit Profile( const QString& id, bool isLocal = false ); + + QString id() const; + + QString name() const; + + QString description() const; + + bool isNull() const; + + void setName( const QString& name ); + + void setDescription( const QString& description ); + + bool operator==( const Kontact::Profile& other ) const; + + QString saveLocation() const; + +private: // ProfileManager only + + enum SetLocalMode { + DoNotCopyProfileFiles, + CopyProfileFiles + }; + void setLocal( SetLocalMode mode ); + bool isLocal() const; + void setOriginalLocation( const QString& path ); + void setId( const QString& id ); + +private: + + static void copyConfigFiles( const QString& source, const QString& dest ); + + QString localSaveLocation() const; + +private: + QString m_id; + QString m_name; + QString m_description; + bool m_local; + QString m_originalLocation; +}; + +class ProfileManager : public QObject +{ +Q_OBJECT +public: + enum ImportError { + SuccessfulImport=0, + NoValidProfile + }; + + enum ExportError { + SuccessfulExport=0, + DirectoryDoesNotExist, + DirectoryNotWritable + }; + + static ProfileManager* self(); + + ~ProfileManager(); + + Kontact::Profile profileById( const QString& id ) const; + + bool addProfile( const Kontact::Profile& profile, bool syncConfig = true ); + + void removeProfile( const Kontact::Profile& profile ); + + void removeProfile( const QString& id ); + + void updateProfile( const Kontact::Profile& profile ); + + void loadProfile( const QString& id ); + + void saveToProfile( const QString& id ); + + QValueList<Kontact::Profile> profiles() const; + + ExportError exportProfileToDirectory( const QString& id, const QString& path ); + + ImportError importProfileFromDirectory( const QString& path ); + + QString generateNewId() const; + +signals: + void profileAdded( const QString& id ); + + void profileRemoved( const QString& id ); + + void profileUpdated( const QString& id ); + + void profileLoaded( const QString& id ); + + void saveToProfileRequested( const QString& id ); + + void profileImportFinished( ImportError status ); + +private: + static ProfileManager* m_self; + + static Kontact::Profile readFromConfiguration( const QString& configFile, bool isLocal ); + + explicit ProfileManager( QObject* parent = 0 ); + + void readConfig(); + + void writeConfig() const; + + void writeProfileConfig( const Kontact::Profile& profile ) const; + +private: + QMap<QString, Kontact::Profile> m_profiles; +}; + +} + +#endif // KONTACT_PROFILEMANAGER_H diff --git a/kontact/src/sidepanebase.cpp b/kontact/src/sidepanebase.cpp new file mode 100644 index 000000000..781556085 --- /dev/null +++ b/kontact/src/sidepanebase.cpp @@ -0,0 +1,52 @@ +/* + This file is part of the KDE Kontact. + + Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "core.h" + +#include "sidepanebase.h" + +using namespace Kontact; + +SidePaneBase::SidePaneBase( Core *core, QWidget *parent, const char *name ) + : QVBox( parent, name ), mCore( core ) +{ +} + +SidePaneBase::~SidePaneBase() +{ +} + +Core* SidePaneBase::core() const +{ + return mCore; +} + +void SidePaneBase::setActionCollection( KActionCollection *actionCollection ) +{ + mActionCollection = actionCollection; +} + +KActionCollection *SidePaneBase::actionCollection() const +{ + return mActionCollection; +} + +#include "sidepanebase.moc" diff --git a/kontact/src/sidepanebase.h b/kontact/src/sidepanebase.h new file mode 100644 index 000000000..95378f919 --- /dev/null +++ b/kontact/src/sidepanebase.h @@ -0,0 +1,79 @@ +/* + This file is part of the KDE Kontact. + + Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef KONTACT_SIDEPANEBASE_H +#define KONTACT_SIDEPANEBASE_H + +#include <qvbox.h> + +namespace KParts { class Part; } + +namespace Kontact +{ + +class Core; +class Plugin; + +class SidePaneBase : public QVBox +{ + Q_OBJECT + public: + SidePaneBase( Core *core, QWidget *parent, const char *name = 0 ); + virtual ~SidePaneBase(); + + void setActionCollection( KActionCollection *actionCollection ); + KActionCollection *actionCollection() const; + + virtual const QPtrList<KAction> & actions() = 0; + + signals: + void pluginSelected( Kontact::Plugin* ); + + public slots: + /** + This method is called by the core whenever the count + of plugins has changed. + */ + virtual void updatePlugins() = 0; + + /** + Select the current plugin without emmiting a signal. + This is used to sync with the core. + */ + virtual void selectPlugin( Kontact::Plugin* ) = 0; + + /** + This is an overloaded member function. It behaves essentially like the + above function. + */ + virtual void selectPlugin( const QString &name ) = 0; + + virtual void indicateForegrunding( Kontact::Plugin* ) = 0; + protected: + Core* core() const; + + private: + Core* mCore; + KActionCollection *mActionCollection; +}; + +} + +#endif |