summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--kaddressbook/kaddressbookview.cpp4
-rw-r--r--kaddressbook/kaddressbookview.h6
-rw-r--r--kaddressbook/views/cardview.cpp31
-rw-r--r--kaddressbook/views/cardview.h7
-rw-r--r--kaddressbook/views/contactlistview.cpp29
-rw-r--r--kaddressbook/views/contactlistview.h4
-rw-r--r--kaddressbook/views/kaddressbookcardview.cpp4
-rw-r--r--kaddressbook/views/kaddressbooktableview.cpp4
-rw-r--r--korganizer/komonthview.cpp19
-rw-r--r--korganizer/komonthview.h3
-rw-r--r--korganizer/mainwindow.cpp26
-rw-r--r--korganizer/mainwindow.h1
12 files changed, 129 insertions, 9 deletions
diff --git a/kaddressbook/kaddressbookview.cpp b/kaddressbook/kaddressbookview.cpp
index 09859c2..86898e2 100644
--- a/kaddressbook/kaddressbookview.cpp
+++ b/kaddressbook/kaddressbookview.cpp
@@ -1,186 +1,188 @@
/*
This file is part of KAddressBook.
Copyright (c) 2002 Mike Pilone <mpilone@slac.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 KAB_EMBEDDED
#include <qapplication.h>
#include <kabc/distributionlistdialog.h>
#include <kconfig.h>
#include <klocale.h>
#include "viewmanager.h"
#endif //KAB_EMBEDDED
#include <qlayout.h>
#include <kabc/distributionlistdialog.h>
#include <kabc/addressbook.h>
#include <kdebug.h>
#include "kaddressbookview.h"
KAddressBookView::KAddressBookView( KABC::AddressBook *ab, QWidget *parent,
const char *name )
: QWidget( parent, name ), mAddressBook( ab ), mFieldList()
{
-
+
initGUI();
}
KAddressBookView::~KAddressBookView()
{
}
QRegExp KAddressBookView::getRegExp( const QString s )
{
QRegExp re;
if ( s.length() == 3 && s.mid(1,1) == "-" ) {
QString pattern = "^[" + s.lower() +"]";
re.setCaseSensitive(false);
re.setPattern( pattern );
} else {
QString pattern = s.lower()+"*";
re.setWildcard(true); // most people understand these better.
re.setCaseSensitive(false);
re.setPattern( pattern );
}
return re;
}
void KAddressBookView::readConfig( KConfig *config )
{
mFieldList = KABC::Field::restoreFields( config, "KABCFields" );
if ( mFieldList.isEmpty() )
mFieldList = KABC::Field::defaultFields();
mDefaultFilterType = (DefaultFilterType)config->readNumEntry( "DefaultFilterType", 1 );
mDefaultFilterName = config->readEntry( "DefaultFilterName", QString::null );
}
void KAddressBookView::writeConfig( KConfig* )
{
// Most of writing the config is handled by the ConfigureViewDialog
}
QString KAddressBookView::selectedEmails()
{
bool first = true;
QString emailAddrs;
QStringList uidList = selectedUids();
KABC::Addressee addr;
QString email;
QStringList::Iterator it;
for ( it = uidList.begin(); it != uidList.end(); ++it ) {
addr = mAddressBook->findByUid( *it );
if ( !addr.isEmpty() ) {
QString m = QString::null;
if ( addr.emails().count() > 1 )
m = KABC::EmailSelector::getEmail( addr.emails(), addr.preferredEmail(), this );
email = addr.fullEmail( m );
if ( !first )
emailAddrs += ", ";
else
first = false;
emailAddrs += email;
}
}
return emailAddrs;
}
KABC::Addressee::List KAddressBookView::addressees()
{
KABC::Addressee::List addresseeList;
KABC::AddressBook::Iterator it;
for (it = mAddressBook->begin(); it != mAddressBook->end(); ++it ) {
if ( mFilter.filterAddressee( *it ) )
addresseeList.append( *it );
}
return addresseeList;
}
void KAddressBookView::initGUI()
{
// Create the layout
QVBoxLayout *layout = new QVBoxLayout( this );
// Add the view widget
mViewWidget = new QWidget( this );
layout->addWidget( mViewWidget );
}
KABC::Field::List KAddressBookView::fields() const
{
return mFieldList;
}
KABC::Field::List KAddressBookView::allFields() const
{
return KABC::Field::allFields();
}
void KAddressBookView::setFilter( const Filter &filter )
{
mFilter = filter;
}
KAddressBookView::DefaultFilterType KAddressBookView::defaultFilterType() const
{
return mDefaultFilterType;
}
const QString &KAddressBookView::defaultFilterName() const
{
return mDefaultFilterName;
}
KABC::AddressBook *KAddressBookView::addressBook() const
{
return mAddressBook;
}
QWidget *KAddressBookView::viewWidget()
{
return mViewWidget;
}
ViewConfigureWidget *ViewFactory::configureWidget( KABC::AddressBook *ab,
QWidget *parent,
const char *name )
{
return new ViewConfigureWidget( ab, parent, name );
}
+
+
#ifndef KAB_EMBEDDED
#include "kaddressbookview.moc"
#endif //KAB_EMBEDDED
diff --git a/kaddressbook/kaddressbookview.h b/kaddressbook/kaddressbookview.h
index 6bbb9c2..3a3f71a 100644
--- a/kaddressbook/kaddressbookview.h
+++ b/kaddressbook/kaddressbookview.h
@@ -1,312 +1,314 @@
/*
This file is part of KAddressBook.
Copyright (c) 2002 Mike Pilone <mpilone@slac.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 KADDRESSBOOKVIEW_H
#define KADDRESSBOOKVIEW_H
#ifndef KAB_EMBEDDED
#include <klibloader.h>
#endif //KAB_EMBEDDED
class KConfig;
class QDropEvent;
#include <qstringlist.h>
#include <kabc/field.h>
#include <qwidget.h>
#include <qregexp.h>
#include "viewconfigurewidget.h"
#include "filter.h"
#ifdef DESKTOP_VERSION
#include <qpaintdevicemetrics.h>
#include <qprinter.h>
#include <qpainter.h>
#endif
namespace KABC { class AddressBook; }
/**
Base class for all views in kaddressbook. This class implements
all the common methods needed to provide a view to the user.
To implement a specific view (table, card, etc), just inherit from
this class and implement all the pure virtuals.
@author Mike Pilone <mpilone@slac.com>
*/
class KAddressBookView : public QWidget
{
Q_OBJECT
public:
enum DefaultFilterType { None = 0, Active = 1, Specific = 2 };
KAddressBookView( KABC::AddressBook *ab, QWidget *parent, const char *name );
virtual ~KAddressBookView();
/**
Must be overloaded in subclasses. Should return a list of
all the uids of selected contacts.
*/
virtual QStringList selectedUids() = 0;
virtual void doSearch( const QString& s ,KABC::Field *field ) = 0;
virtual void scrollUP() = 0;
virtual void scrollDOWN() = 0;
virtual void setFocusAV() = 0;
/**
Called whenever this view should read the config. This can be used
as a sign that the config has changed, therefore the view should
assume the worst and rebuild itself if necessary. For example,
in a table view this method may be called when the user adds or
removes columns from the view.
If overloaded in the subclass, do not forget to call super class's
method.
@param config The KConfig object to read from. The group will already
be set, so do not change the group.
*/
virtual void readConfig( KConfig *config );
/**
Called whenever this view should write the config. The view should not
write out information handled by the application, such as which fields
are visible. The view should only write out information specific
to itself (i.e.: All information in the ViewConfigWidget)
If overloaded in the subclass, do not forget to call the super class's
method.
@param config The KConfig object to read from. The group will already
be set, so do not change the group.
*/
virtual void writeConfig( KConfig *config );
/**
Returns a QString with all the selected email addresses concatenated
together with a ',' seperator.
*/
virtual QString selectedEmails();
/**
Return the type of the view: Icon, Table, etc. Please make sure that
this is the same value that ViewWrapper::type() will return for your
view.
*/
virtual QString type() const = 0;
/**
Returns a list of the fields that should be displayed. The list
is composed of the fields proper names (ie: Home Address), so
the view may need to translate them in order to get the
value from the addressee.
This list is generated from the config file, so it is advisable to call
this method whenever a readConfig() is called in order to get the newest
list of fields.
*/
KABC::Field::List fields() const;
KABC::Field::List allFields() const;
/**
Sets the active filter. This filter will be used for filtering
the list of addressees to display. The view will <b>not</b>
automatically refresh itself, so in most cases you will want to call
KAddressBookView::refresh() after this method.
*/
void setFilter( const Filter& );
/**
@return The default filter type selection. If the selection
is SpecificFilter, the name of the filter can be retrieved with
defaultFilterName()
*/
DefaultFilterType defaultFilterType() const;
/**
@return The name of the default filter. This string is
only valid if defaultFilterType() is returning SpecificFilter.
*/
const QString &defaultFilterName() const;
/**
@return The address book.
*/
KABC::AddressBook *addressBook() const;
void printMyView() { emit printView() ;}
public slots:
/**
Must be overloaded in subclasses to refresh the view.
Refreshing includes updating the view to ensure that only items
in the document are visible. If <i>uid</i> is valid, only the
addressee with uid needs to be refreshed. This is an optimization
only.
*/
virtual void refresh( QString uid = QString::null ) = 0;
/**
This method must be overloaded in subclasses. Select (highlight)
the addressee matching <i>uid</i>. If uid
is equal to QString::null, then all addressees should be selected.
*/
#ifndef KAB_EMBEDDED
//MOC_SKIP_BEGIN
virtual void setSelected( QString uid = QString::null, bool selected = true ) = 0;
//MOC_SKIP_END
#else //KAB_EMBEDDED
//US my moc can not handle the default parameters. Is this a problem ???
virtual void setSelected( QString uid, bool selected) = 0;
#endif //KAB_EMBEDDED
signals:
void printView();
/**
This signal should be emitted by a subclass whenever an addressee
is modified.
*/
void modified();
/**
This signal should be emitted by a subclass whenever an addressee
is selected. Selected means that the addressee was given the focus.
Some widgets may call this 'highlighted'. The view is responsible for
emitting this signal multiple times if multiple items are selected,
with the last item selected being the last emit.
@param uid The uid of the selected addressee.
@see KListView
*/
void selected( const QString &uid );
void deleteRequest();
/**
This signal should be emitted by a subclass whenever an addressee
is executed. This is defined by the KDE system wide config, but it
either means single or doubleclicked.
@param ui The uid of the selected addressee
@see KListView
*/
void executed( const QString &uid );
/**
This signal is emitted whenever a user attempts to start a drag
in the view. The slot connected to this signal would usually want
to create a QDragObject.
*/
void startDrag();
/**
This signal is emitted whenever the user drops something on the
view. The individual view should handle checking if the item is
droppable (ie: if it is a vcard).
*/
void dropped( QDropEvent* );
- protected:
+ protected:
+
/**
Returns a list of the addressees that should be displayed. This method
should always be used by the subclass to get a list of addressees. This
method internally takes many factors into account, including the current
filter.
*/
KABC::Addressee::List addressees();
/**
This method returns the widget that should be used as the parent for
all view components. By using this widget as the parent and not
'this', the view subclass has the option of placing other widgets
around the view (ie: search fields, etc). Do not delete this widget!
*/
QWidget *viewWidget();
QRegExp getRegExp( const QString );
private:
void initGUI();
DefaultFilterType mDefaultFilterType;
Filter mFilter;
QString mDefaultFilterName;
KABC::AddressBook *mAddressBook;
KABC::Field::List mFieldList;
QWidget *mViewWidget;
};
#ifndef KAB_EMBEDDED
//MOC_SKIP_BEGIN
class ViewFactory : public KLibFactory
//MOC_SKIP_END
#else //KAB_EMBEDDED
class ViewFactory
#endif //KAB_EMBEDDED
{
public:
virtual KAddressBookView *view( KABC::AddressBook *ab, QWidget *parent,
const char *name = 0 ) = 0;
/**
@return The type of the view. This is normally a small one word
string (ie: Table, Icon, Tree, etc).
*/
virtual QString type() const = 0;
/**
@return The description of the view. This should be a 3 to
4 line string (don't actually use return characters in the string)
describing the features offered by the view.
*/
virtual QString description() const = 0;
/**
Creates a config dialog for the view type. The default
implementation will return a ViewConfigDialog. This default
dialog will allow the user to set the visible fields only. If
you need more config options (as most views will), this method
can be overloaded to return your sublcass of ViewConfigDialog.
If this method is over loaded the base classes method should
<B>not</B> be called.
*/
virtual ViewConfigureWidget *configureWidget( KABC::AddressBook *ab,
QWidget *parent,
const char *name = 0 );
protected:
virtual QObject* createObject( QObject*, const char*, const char*,
const QStringList & )
{
return 0;
- }
+ }
+
};
#endif
diff --git a/kaddressbook/views/cardview.cpp b/kaddressbook/views/cardview.cpp
index 03df444..84d3116 100644
--- a/kaddressbook/views/cardview.cpp
+++ b/kaddressbook/views/cardview.cpp
@@ -1,1722 +1,1751 @@
/*
This file is part of KAddressBook.
Copyright (c) 2002 Mike Pilone <mpilone@slac.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.
*/
//BEGIN Includes
#include "cardview.h"
#include <limits.h>
#include <qpainter.h>
#include <qtimer.h>
#include <qdatetime.h>
#include <qlabel.h>
#include <qstyle.h>
#include <qcursor.h>
#include <qtooltip.h>
+#include <qapplication.h>
#include "kabprefs.h"
#include <kdebug.h>
#include <kglobalsettings.h>
//END includes
#define MIN_ITEM_WIDTH 80
//BEGIN Helpers
//////////////////////////////////////
// CardViewTip
class CardViewTip : public QLabel {
public:
CardViewTip(QWidget *parent=0, const char *name=0) : QLabel( parent, name )
{
setPalette( QToolTip::palette() );
setFrameStyle( Panel|Plain );
setMidLineWidth(0);
setIndent(1);
}
~CardViewTip() {};
protected:
void leaveEvent( QEvent * )
{
hide();
}
};
//////////////////////////////////////
// CardViewItemList
//
// Warning: make sure you use findRef() instead of find() to find an
// item! Only the pointer value is unique in the list.
//
class CardViewItemList : public QPtrList<CardViewItem>
{
protected:
virtual int compareItems(QPtrCollection::Item item1,
QPtrCollection::Item item2)
{
CardViewItem *cItem1 = (CardViewItem*)item1;
CardViewItem *cItem2 = (CardViewItem*)item2;
if ( cItem1 == cItem2 )
return 0;
if ((cItem1 == 0) || (cItem2 == 0))
return cItem1 ? -1 : 1;
if (cItem1->caption() < cItem2->caption())
return -1;
else if (cItem1->caption() > cItem2->caption())
return 1;
return 0;
}
private:
/*int find( const CardViewItem * )
{
qDebug("DON'T USE CardViewItemList::find( item )! Use findRef( item )!");
}*/
};
//////////////////////////////////////
// CardViewSeparator
class CardViewSeparator
{
friend class CardView;
public:
CardViewSeparator(CardView *view)
: mView(view)
{
mRect = QRect(0, 0, view->separatorWidth(), 0);
}
~CardViewSeparator() {}
void paintSeparator(QPainter *p, QColorGroup &cg)
{
p->fillRect(0, 0, mRect.width(), mRect.height(),
cg.brush(QColorGroup::Button));
}
void repaintSeparator()
{
mView->repaintContents(mRect);
}
private:
CardView *mView;
QRect mRect;
};
//END Helpers
//BEGIN Private Data
class CardViewPrivate
{
public:
CardViewPrivate()
: mSelectionMode( CardView::Multi ),
mDrawCardBorder( true ),
mDrawFieldLabels( true ),
mDrawSeparators( true),
mSepWidth( 2 ),
mShowEmptyFields( false ),
mLayoutDirty( true ),
mLastClickOnItem( false ),
mItemMargin( 0 ),
mItemSpacing( 10 ),
mItemWidth( 200 ),
mMaxFieldLines( INT_MAX ),
mCurrentItem( 0L ),
mLastClickPos( QPoint(0, 0) ),
mResizeAnchor(0),
mRubberBandAnchor( 0 ),
mCompText( QString::null )
{};
CardViewItemList mItemList;
QPtrList<CardViewSeparator> mSeparatorList;
QFontMetrics *mFm;
QFontMetrics *mBFm; // bold font
QFont mHeaderFont; // custom header font
CardView::SelectionMode mSelectionMode;
bool mDrawCardBorder;
bool mDrawFieldLabels;
bool mDrawSeparators;
int mSepWidth;
bool mShowEmptyFields;
bool mLayoutDirty;
bool mLastClickOnItem;
uint mItemMargin; // internal margin in items
uint mItemSpacing; // spacing between items, column seperators and border
int mItemWidth; // width of all items
uint mMaxFieldLines; // Max lines to dispaly pr field
CardViewItem *mCurrentItem;
QPoint mLastClickPos;
QTimer *mTimer; // times out if mouse rests for more than 500 msecs
CardViewTip *mTip; // passed to the item under a resting cursor to display full text
bool mOnSeparator; // set/reset on mouse movement
// for resizing by dragging the separators
int mResizeAnchor; // uint, ulong? the mouse down separator left
int mRubberBandAnchor; // for erasing rubber bands
// data used for resizing.
// as they are beeded by each mouse move while resizing, we store them here,
// saving 8 calculations in each mouse move.
int colspace; // amount of space between items pr column
uint first; // the first col to anchor at for painting rubber bands
int firstX; // X position of first in pixel
int pressed; // the colummn that was pressed on at resizing start
int span; // pressed - first
// key completion
QString mCompText; // current completion string
QDateTime mCompUpdated; // ...was updated at this time
};
class CardViewItemPrivate
{
public:
CardViewItemPrivate() :
mSelected( false ),
x( 0 ),
y( 0 ){};
QString mCaption;
QPtrList< CardViewItem::Field > mFieldList;
bool mSelected;
int x; // horizontal position, set by the view
int y; // vertical position, set by the view
int maxLabelWidth; // the width of the widest label, according to the view font.
int hcache; // height cache
};
//END Private Data
//BEGIN CardViewItem
CardViewItem::CardViewItem(CardView *parent, QString caption)
: d(new CardViewItemPrivate()), mView(parent)
{
d->mCaption = caption;
initialize();
}
CardViewItem::~CardViewItem()
{
// Remove ourself from the view
if (mView != 0)
mView->takeItem(this);
delete d;
d = 0;
}
void CardViewItem::initialize()
{
d->mSelected = false;
d->mFieldList.setAutoDelete(true);
d->maxLabelWidth = 0;
d->hcache=0;
//calcRect();
// Add ourself to the view
if (mView != 0)
mView->insertItem(this);
}
void CardViewItem::paintCard(QPainter *p, QColorGroup &cg)
{
if (!mView)
return;
QPen pen;
QBrush brush;
QFontMetrics fm = *(mView->d->mFm);
QFontMetrics bFm = *(mView->d->mBFm);
bool drawLabels = mView->d->mDrawFieldLabels;
bool drawBorder = mView->d->mDrawCardBorder;
int mg = mView->itemMargin();
int w = mView->itemWidth() - (mg*2);
int h = height() - (mg*2);
const int colonWidth( fm.width(":") );
int labelXPos = 2 + mg;
int labelWidth = QMIN( w/2 - 4 - mg, d->maxLabelWidth + colonWidth + 4 );
int valueXPos = labelWidth + 4 + mg;
int valueWidth = w - labelWidth - 4 - mg;
p->setFont( mView->font() );
labelWidth -= colonWidth; // extra space for the colon
if (!drawLabels)
{
valueXPos = labelXPos;
valueWidth = w - 4;
}
// Draw a simple box
if (isSelected())
pen = QPen(cg.highlight(), 1);
else
pen = QPen(cg.button(), 1);
p->setPen(pen);
// Draw the border - this is only draw if the user asks for it.
if (drawBorder)
p->drawRect( mg, mg, w, h );
// set the proper pen color for the caption box
if (isSelected())
brush = cg.brush(QColorGroup::Highlight);
else
brush = cg.brush(QColorGroup::Button);
p->fillRect(mg, mg, w, 4 + bFm.height(), brush);
// Now paint the caption
p->save();
QFont bFont = mView->headerFont();
//bFont.setBold(true);
p->setFont(bFont);
if (isSelected())
p->setPen(cg.highlightedText());
else
p->setPen(cg.buttonText());
p->drawText(2+mg, 2+mg + bFm.ascent()/*bFm.height()*//*-bFm.descent()*//*-bFm.leading()*/, trimString(d->mCaption, w-4, bFm));
p->restore();
// Go through the fields and draw them
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
QString label, value;
int yPos = mg + 4 + bFm.height()/* + 1*/ + fm.height(); // why the + 1 ??? (anders)
p->setPen(cg.text());
int fh = fm.height();
int cln( 0 );
QString tmp;
int maxLines = mView->maxFieldLines();
for (iter.toFirst(); iter.current(); ++iter)
{
value = (*iter)->second;
if ( value.isEmpty() && ! mView->d->mShowEmptyFields )
continue;
if (drawLabels)
{
label = trimString((*iter)->first, labelWidth, fm);
p->drawText(labelXPos, yPos, label + ":");
}
/* US original
for (cln=0; cln <= maxLines; cln++)
{
tmp = value.section('\n',cln,cln);
if ( !tmp.isEmpty() ) p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) );
else break;
}
*/
//US new implementation
QStringList strlst = QStringList::split('\n', value, true);
for (cln=0; cln <= maxLines && cln <= (int)strlst.count(); cln++)
{
tmp = strlst[cln];
if ( !tmp.isEmpty() )
p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) );
else
break;
}
if ( cln == 0 ) cln = 1;
yPos += cln * fh + 2;
}
// if we are the current item and the view has focus, draw focus rect
if ( mView->currentItem() == this && mView->hasFocus() )
{
/*US
mView->style().drawPrimitive( QStyle::PE_FocusRect, p,
QRect(0, 0, mView->itemWidth(), h+(2*mg)), cg,
QStyle::Style_FocusAtBorder,
QStyleOption( isSelected() ? cg.highlight() : cg.base() ) );
*/
const QColor pHighl = isSelected() ? cg.highlight() : cg.base();
const QRect r(0, 0, mView->itemWidth(), h+(2*mg));
#ifndef DESKTOP_VERSION
mView->style().drawFocusRect(p, r, cg, &pHighl, true);
#endif
}
}
const QString &CardViewItem::caption() const
{
return d->mCaption;
}
int CardViewItem::height( bool allowCache ) const
{
// use cache
if ( allowCache && d->hcache )
return d->hcache;
// Base height:
// 2 for line width
// 2 for top caption pad
// 2 for bottom caption pad
// 2 pad for the end
// + 2 times the advised margin
int baseHeight = 8 + ( 2 * mView->itemMargin() );
// size of font for each field
// 2 pad for each field
// anders: if the view does not show empty fields, check for value
bool sef = mView->showEmptyFields();
int fh = mView->d->mFm->height();//lineSpacing(); // font height
//int sp = QMAX( 0, 2- mView->d->mFm->leading() ); // field spacing NOTE make a property
int fieldHeight = 0;
int lines;
int maxLines( mView->maxFieldLines() );
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
for (iter.toFirst(); iter.current(); ++iter)
{
if ( !sef && (*iter)->second.isEmpty() )
continue;
lines = QMIN( (*iter)->second.contains('\n') + 1, maxLines );
fieldHeight += ( lines * fh ) + 2;//sp;
}
// height of caption font (bold)
fieldHeight += mView->d->mBFm->height();
d->hcache = baseHeight + fieldHeight;
return d->hcache;
}
bool CardViewItem::isSelected() const
{
return d->mSelected;
}
void CardViewItem::setSelected(bool selected)
{
d->mSelected = selected;
}
void CardViewItem::insertField(const QString &label, const QString &value)
{
CardViewItem::Field *f = new CardViewItem::Field(label, value);
d->mFieldList.append(f);
d->hcache=0;
if (mView)
{
mView->setLayoutDirty(true);
d->maxLabelWidth = QMAX( mView->d->mFm->width( label ), d->maxLabelWidth );
}
}
void CardViewItem::removeField(const QString &label)
{
CardViewItem::Field *f;
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
for (iter.toFirst(); iter.current(); ++iter)
{
f = *iter;
if (f->first == label)
break;
}
if (*iter)
d->mFieldList.remove(*iter);
d->hcache = 0;
if (mView)
mView->setLayoutDirty(true);
}
void CardViewItem::clearFields()
{
d->mFieldList.clear();
d->hcache = 0;
if (mView)
mView->setLayoutDirty(true);
}
QString CardViewItem::trimString(const QString &text, int width,
QFontMetrics &fm)
{
if (fm.width(text) <= width)
return text;
QString dots = "...";
int dotWidth = fm.width(dots);
QString trimmed;
int charNum = 0;
while (fm.width(trimmed) + dotWidth < width)
{
trimmed += text[charNum];
charNum++;
}
// Now trim the last char, since it put the width over the top
trimmed = trimmed.left(trimmed.length()-1);
trimmed += dots;
return trimmed;
}
CardViewItem *CardViewItem::nextItem()
{
CardViewItem *item = 0;
if (mView)
item = mView->itemAfter(this);
return item;
}
void CardViewItem::repaintCard()
{
if (mView)
mView->repaintItem(this);
}
void CardViewItem::setCaption(const QString &caption)
{
d->mCaption = caption;
repaintCard();
}
QString CardViewItem::fieldValue(const QString &label)
{
QPtrListIterator< CardViewItem::Field > iter(d->mFieldList);
for (iter.toFirst(); iter.current(); ++iter)
if ((*iter)->first == label)
return (*iter)->second;
return QString();
}
void CardViewItem::showFullString( const QPoint &itempos, CardViewTip *tip )
{
bool trimmed( false );
QString s;
int mrg = mView->itemMargin();
int y = mView->d->mBFm->height() + 6 + mrg;
int w = mView->itemWidth() - (2*mrg);
int lw;
bool drawLabels = mView->drawFieldLabels();
bool isLabel = drawLabels && itempos.x() < w/2 ? true : false;
if ( itempos.y() < y )
{
if ( itempos.y() < 8 + mrg || itempos.y() > y - 4 )
return;
// this is the caption
s = caption();
trimmed = mView->d->mBFm->width( s ) > w - 4;
y = 2 + mrg;
lw = 0;
isLabel=true;
} else {
// find the field
Field *f = fieldAt( itempos );
if ( !f || ( !mView->showEmptyFields() && f->second.isEmpty() ) )
return;
// y position:
// header font height + 4px hader margin + 2px leading + item margin
// + actual field index * (fontheight + 2px leading)
int maxLines = mView->maxFieldLines();
bool se = mView->showEmptyFields();
int fh = mView->d->mFm->height();
// {
Field *_f;
for (_f = d->mFieldList.first(); _f != f; _f = d->mFieldList.next())
if ( se || ! _f->second.isEmpty() )
y += ( QMIN(_f->second.contains('\n')+1, maxLines) * fh ) + 2;
// }
if ( isLabel && itempos.y() > y + fh )
return;
// label or data?
s = isLabel ? f->first : f->second;
// trimmed?
int colonWidth = mView->d->mFm->width(":");
lw = drawLabels ? // label width
QMIN( w/2 - 4 - mrg, d->maxLabelWidth + colonWidth + 4 ) :
0;
int mw = isLabel ? lw - colonWidth : w - lw - (mrg*2); // max width for string
if ( isLabel )
{
trimmed = mView->d->mFm->width( s ) > mw - colonWidth;
} else {
QRect r( mView->d->mFm->boundingRect( 0, 0, INT_MAX, INT_MAX, Qt::AlignTop|Qt::AlignLeft, s ) );
trimmed = r.width() > mw || r.height()/fh > QMIN(s.contains('\n') + 1, maxLines);
}
}
if ( trimmed )
{
tip->setFont( (isLabel && !lw) ? mView->headerFont() : mView->font() ); // if condition is true, a header
tip->setText( s );
tip->adjustSize();
// find a proper position
int lx;
lx = isLabel || !drawLabels ? mrg : lw + mrg + 2 /*-1*/;
QPoint pnt(mView->contentsToViewport( QPoint(d->x, d->y) ));
pnt += QPoint(lx, y);
if ( pnt.x() < 0 )
pnt.setX( 0 );
if ( pnt.x() + tip->width() > mView->visibleWidth() )
pnt.setX( mView->visibleWidth() - tip->width() );
if ( pnt.y() + tip->height() > mView->visibleHeight() )
pnt.setY( QMAX( 0, mView->visibleHeight() - tip->height() ) );
// show
tip->move( pnt );
tip->show();
}
}
CardViewItem::Field *CardViewItem::fieldAt( const QPoint & itempos ) const
{
int ypos = mView->d->mBFm->height() + 7 + mView->d->mItemMargin;
int iy = itempos.y();
// skip below caption
if ( iy <= ypos )
return 0;
// try find a field
bool showEmpty = mView->showEmptyFields();
int fh = mView->d->mFm->height();
int maxLines = mView->maxFieldLines();
Field *f;
for ( f = d->mFieldList.first(); f; f = d->mFieldList.next() )
{
if ( showEmpty || !f->second.isEmpty() )
ypos += ( QMIN( f->second.contains('\n')+1, maxLines ) *fh)+2;
if ( iy <= ypos )
break;
}
return f ? f : 0;
}
//END CardViewItem
//BEGIN CardView
CardView::CardView(QWidget *parent, const char *name)
: QScrollView(parent, name),
d(new CardViewPrivate())
{
+ mFlagKeyPressed = false;
+ mFlagBlockKeyPressed = false;
d->mItemList.setAutoDelete(true);
d->mSeparatorList.setAutoDelete(true);
QFont f = font();
d->mFm = new QFontMetrics(f);
f.setBold(true);
d->mHeaderFont = f;
d->mBFm = new QFontMetrics(f);
d->mTip = ( new CardViewTip( viewport() ) ),
d->mTip->hide();
d->mTimer = ( new QTimer(this, "mouseTimer") ),
viewport()->setMouseTracking( true );
viewport()->setFocusProxy(this);
viewport()->setFocusPolicy(WheelFocus);
viewport()->setBackgroundMode(PaletteBase);
connect( d->mTimer, SIGNAL(timeout()), this, SLOT(tryShowFullText()) );
//US setBackgroundMode(PaletteBackground, PaletteBase);
setBackgroundMode(PaletteBackground);
// no reason for a vertical scrollbar
setVScrollBarMode(AlwaysOff);
}
CardView::~CardView()
{
delete d->mFm;
delete d->mBFm;
delete d;
d = 0;
}
void CardView::insertItem(CardViewItem *item)
{
d->mItemList.inSort(item);
setLayoutDirty(true);
}
void CardView::takeItem(CardViewItem *item)
{
if ( d->mCurrentItem == item )
d->mCurrentItem = item->nextItem();
d->mItemList.take(d->mItemList.findRef(item));
setLayoutDirty(true);
}
void CardView::clear()
{
d->mItemList.clear();
setLayoutDirty(true);
}
CardViewItem *CardView::currentItem()
{
if ( ! d->mCurrentItem && d->mItemList.count() )
d->mCurrentItem = d->mItemList.first();
return d->mCurrentItem;
}
void CardView::setCurrentItem( CardViewItem *item )
{
if ( !item )
return;
else if ( item->cardView() != this )
{
kdDebug(5720)<<"CardView::setCurrentItem: Item ("<<item<<") not owned! Backing out.."<<endl;
return;
}
else if ( item == currentItem() )
{
return;
}
if ( d->mSelectionMode == Single )
{
setSelected( item, true );
}
else
{
CardViewItem *it = d->mCurrentItem;
d->mCurrentItem = item;
if ( it )
it->repaintCard();
item->repaintCard();
}
if ( ! d->mOnSeparator )
ensureItemVisible( item );
emit currentChanged( item );
}
CardViewItem *CardView::itemAt(const QPoint &viewPos)
{
CardViewItem *item = 0;
QPtrListIterator<CardViewItem> iter(d->mItemList);
bool found = false;
for (iter.toFirst(); iter.current() && !found; ++iter)
{
item = *iter;
//if (item->d->mRect.contains(viewPos))
if (QRect(item->d->x, item->d->y, d->mItemWidth, item->height()).contains(viewPos))
found = true;
}
if (found)
return item;
return 0;
}
QRect CardView::itemRect(const CardViewItem *item)
{
//return item->d->mRect;
return QRect(item->d->x, item->d->y, d->mItemWidth, item->height());
}
void CardView::ensureItemVisible(const CardViewItem *item)
{
ensureVisible(item->d->x , item->d->y, d->mItemSpacing, 0);
ensureVisible(item->d->x + d->mItemWidth, item->d->y, d->mItemSpacing, 0);
}
void CardView::repaintItem(const CardViewItem *item)
{
//repaintContents(item->d->mRect);
repaintContents( QRect(item->d->x, item->d->y, d->mItemWidth, item->height()) );
}
void CardView::setSelectionMode(CardView::SelectionMode mode)
{
selectAll(false);
d->mSelectionMode = mode;
}
CardView::SelectionMode CardView::selectionMode() const
{
return d->mSelectionMode;
}
void CardView::selectAll(bool state)
{
QPtrListIterator<CardViewItem> iter(d->mItemList);
if (!state)
{
for (iter.toFirst(); iter.current(); ++iter)
{
if ((*iter)->isSelected())
{
(*iter)->setSelected(false);
(*iter)->repaintCard();
}
}
//emit selectionChanged(); // WARNING FIXME
emit selectionChanged(0);
}
else if (d->mSelectionMode != CardView::Single)
{
for (iter.toFirst(); iter.current(); ++iter)
{
(*iter)->setSelected(true);
}
if (d->mItemList.count() > 0)
{
// emit, since there must have been at least one selected
emit selectionChanged();
//repaint();//???
viewport()->update();
}
}
}
void CardView::setSelected(CardViewItem *item, bool selected)
{
if ((item == 0) || (item->isSelected() == selected))
return;
if ( selected && d->mCurrentItem != item )
{
CardViewItem *it = d->mCurrentItem;
d->mCurrentItem = item;
if ( it )
it->repaintCard();
}
if (d->mSelectionMode == CardView::Single)
{
bool b = signalsBlocked();
blockSignals(true);
selectAll(false);
blockSignals(b);
if (selected)
{
item->setSelected(selected);
item->repaintCard();
emit selectionChanged();
emit selectionChanged(item);
}
else
{
emit selectionChanged();
emit selectionChanged(0);
}
}
else if (d->mSelectionMode == CardView::Multi)
{
item->setSelected(selected);
item->repaintCard();
emit selectionChanged();
}
else if (d->mSelectionMode == CardView::Extended)
{
bool b = signalsBlocked();
blockSignals(true);
selectAll(false);
blockSignals(b);
item->setSelected(selected);
item->repaintCard();
emit selectionChanged();
}
}
bool CardView::isSelected(CardViewItem *item) const
{
return (item && item->isSelected());
}
CardViewItem *CardView::selectedItem() const
{
// find the first selected item
QPtrListIterator<CardViewItem> iter(d->mItemList);
for (iter.toFirst(); iter.current(); ++iter)
{
if ((*iter)->isSelected())
return *iter;
}
return 0;
}
CardViewItem *CardView::firstItem() const
{
return d->mItemList.first();
}
int CardView::childCount() const
{
return d->mItemList.count();
}
/*US
CardViewItem *CardView::findItem(const QString &text, const QString &label,
Qt::StringComparisonMode compare)
{
// IF the text is empty, we will return null, since empty text will
// match anything!
if (text.isEmpty())
return 0;
QPtrListIterator<CardViewItem> iter(d->mItemList);
if (compare & Qt::BeginsWith)
{
QString value;
for (iter.toFirst(); iter.current(); ++iter)
{
value = (*iter)->fieldValue(label).upper();
if (value.startsWith(text.upper()))
return *iter;
}
}
else
{
kdDebug(5720) << "CardView::findItem: search method not implemented" << endl;
}
return 0;
}
*/
uint CardView::columnWidth()
{
return d->mDrawSeparators ?
d->mItemWidth + ( 2 * d->mItemSpacing ) + d->mSepWidth :
d->mItemWidth + d->mItemSpacing;
}
void CardView::drawContents(QPainter *p, int clipx, int clipy,
int clipw, int cliph)
{
QScrollView::drawContents(p, clipx, clipy, clipw, cliph);
if (d->mLayoutDirty)
calcLayout();
//kdDebug() << "CardView::drawContents: " << clipx << ", " << clipy
// << ", " << clipw << ", " << cliph << endl;
QColorGroup cg = viewport()->palette().active(); // allow setting costum colors in the viewport pale
QRect clipRect(clipx, clipy, clipw, cliph);
QRect cardRect;
QRect sepRect;
CardViewItem *item;
CardViewSeparator *sep;
// make sure the viewport is a pure background
viewport()->erase(clipRect);
// Now tell the cards to draw, if they are in the clip region
QPtrListIterator<CardViewItem> iter(d->mItemList);
for (iter.toFirst(); iter.current(); ++iter)
{
item = *iter;
cardRect.setRect( item->d->x, item->d->y, d->mItemWidth, item->height() );
if (clipRect.intersects(cardRect) || clipRect.contains(cardRect))
{
//kdDebug() << "\trepainting card at: " << cardRect.x() << ", "
// << cardRect.y() << endl;
// Tell the card to paint
p->save();
p->translate(cardRect.x(), cardRect.y());
item->paintCard(p, cg);
p->restore();
}
}
// Followed by the separators if they are in the clip region
QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList);
for (sepIter.toFirst(); sepIter.current(); ++sepIter)
{
sep = *sepIter;
sepRect = sep->mRect;
if (clipRect.intersects(sepRect) || clipRect.contains(sepRect))
{
p->save();
p->translate(sepRect.x(), sepRect.y());
sep->paintSeparator(p, cg);
p->restore();
}
}
}
void CardView::resizeEvent(QResizeEvent *e)
{
QScrollView::resizeEvent(e);
setLayoutDirty(true);
}
void CardView::calcLayout()
{
//kdDebug() << "CardView::calcLayout:" << endl;
// Start in the upper left corner and layout all the
// cars using their height and width
int maxWidth = 0;
int maxHeight = 0;
int xPos = 0;
int yPos = 0;
int cardSpacing = d->mItemSpacing;
// delete the old separators
d->mSeparatorList.clear();
QPtrListIterator<CardViewItem> iter(d->mItemList);
CardViewItem *item = 0;
CardViewSeparator *sep = 0;
xPos += cardSpacing;
for (iter.toFirst(); iter.current(); ++iter)
{
item = *iter;
yPos += cardSpacing;
if (yPos + item->height() + cardSpacing >= height() - horizontalScrollBar()->height())
{
maxHeight = QMAX(maxHeight, yPos);
// Drawing in this column would be greater than the height
// of the scroll view, so move to next column
yPos = cardSpacing;
xPos += cardSpacing + maxWidth;
if (d->mDrawSeparators)
{
// Create a separator since the user asked
sep = new CardViewSeparator(this);
sep->mRect.moveTopLeft(QPoint(xPos, yPos+d->mItemMargin));
xPos += d->mSepWidth + cardSpacing;
d->mSeparatorList.append(sep);
}
maxWidth = 0;
}
item->d->x = xPos;
item->d->y = yPos;
yPos += item->height();
maxWidth = QMAX(maxWidth, d->mItemWidth);
}
xPos += maxWidth;
resizeContents( xPos + cardSpacing, maxHeight );
// Update the height of all the separators now that we know the
// max height of a column
QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList);
for (sepIter.toFirst(); sepIter.current(); ++sepIter)
{
(*sepIter)->mRect.setHeight(maxHeight - 2*cardSpacing - 2*d->mItemMargin);
}
d->mLayoutDirty = false;
}
CardViewItem *CardView::itemAfter(CardViewItem *item)
{
/*int pos = */d->mItemList.findRef(item);
return d->mItemList.next();//at(pos+1);
}
uint CardView::itemMargin()
{
return d->mItemMargin;
}
void CardView::setItemMargin( uint margin )
{
if ( margin == d->mItemMargin )
return;
d->mItemMargin = margin;
setLayoutDirty( true );
}
uint CardView::itemSpacing()
{
return d->mItemSpacing;
}
void CardView::setItemSpacing( uint spacing )
{
if ( spacing == d->mItemSpacing )
return;
d->mItemSpacing = spacing;
setLayoutDirty( true );
}
void CardView::contentsMousePressEvent(QMouseEvent *e)
{
QScrollView::contentsMousePressEvent(e);
QPoint pos = e->pos();
d->mLastClickPos = pos;
CardViewItem *item = itemAt(pos);
if (item == 0)
{
d->mLastClickOnItem = false;
if ( d->mOnSeparator)
{
d->mResizeAnchor = e->x()+contentsX();
d->colspace = (2*d->mItemSpacing) /*+ (2*d->mItemMargin)*/;
int ccw = d->mItemWidth + d->colspace + d->mSepWidth;
d->first = (contentsX()+d->mSepWidth)/ccw;
d->pressed = (d->mResizeAnchor+d->mSepWidth)/ccw;
d->span = d->pressed - d->first;
d->firstX = d->first * ccw;
if ( d->firstX ) d->firstX -= d->mSepWidth; // (no sep in col 0)
}
else
{
selectAll(false);
}
return;
}
d->mLastClickOnItem = true;
CardViewItem *other = d->mCurrentItem;
setCurrentItem( item );
// Always emit the selection
emit clicked(item);
// Check the selection type and update accordingly
if (d->mSelectionMode == CardView::Single)
{
// make sure it isn't already selected
if (item->isSelected())
return;
bool b = signalsBlocked();
blockSignals(true);
selectAll(false);
blockSignals(b);
item->setSelected(true);
item->repaintCard();
emit selectionChanged(item);
}
else if (d->mSelectionMode == CardView::Multi)
{
// toggle the selection
item->setSelected(!item->isSelected());
item->repaintCard();
emit selectionChanged();
}
else if (d->mSelectionMode == CardView::Extended)
{
if ((e->button() & Qt::LeftButton) &&
(e->state() & Qt::ShiftButton))
{
if ( item == other ) return;
bool s = ! item->isSelected();
if ( s && ! (e->state() & ControlButton) )
{
bool b = signalsBlocked();
blockSignals(true);
selectAll(false);
blockSignals(b);
}
int from, to, a, b;
a = d->mItemList.findRef( item );
b = d->mItemList.findRef( other );
from = a < b ? a : b;
to = a > b ? a : b;
//kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl;
CardViewItem *aItem;
for ( ; from <= to; from++ )
{
aItem = d->mItemList.at( from );
aItem->setSelected( s );
repaintItem( aItem );
}
emit selectionChanged();
}
else if ((e->button() & Qt::LeftButton) &&
(e->state() & Qt::ControlButton))
{
item->setSelected(!item->isSelected());
item->repaintCard();
emit selectionChanged();
}
else if (e->button() & Qt::LeftButton)
{
bool b = signalsBlocked();
blockSignals(true);
selectAll(false);
blockSignals(b);
item->setSelected(true);
item->repaintCard();
emit selectionChanged();
}
}
}
void CardView::contentsMouseReleaseEvent(QMouseEvent *e)
{
QScrollView::contentsMouseReleaseEvent(e);
if ( d->mResizeAnchor )
{
// finish the resizing:
unsetCursor();
// hide rubber bands
int newiw = d->mItemWidth - ((d->mResizeAnchor - d->mRubberBandAnchor)/d->span);
drawRubberBands( 0 );
// we should move to reflect the new position if we are scrolled.
if ( contentsX() )
{
int newX = QMAX( 0, ( d->pressed * ( newiw + d->colspace + d->mSepWidth ) ) - e->x() );
setContentsPos( newX, contentsY() );
}
// set new item width
setItemWidth( newiw );
// reset anchors
d->mResizeAnchor = 0;
d->mRubberBandAnchor = 0;
return;
}
// If there are accel keys, we will not emit signals
if ((e->state() & Qt::ShiftButton) || (e->state() & Qt::ControlButton))
return;
// Get the item at this position
CardViewItem *item = itemAt(e->pos());
if (item && KABPrefs::instance()->mHonorSingleClick)
{
emit executed(item);
}
}
void CardView::contentsMouseDoubleClickEvent(QMouseEvent *e)
{
QScrollView::contentsMouseDoubleClickEvent(e);
CardViewItem *item = itemAt(e->pos());
if (item)
{
d->mCurrentItem = item;
}
if (item && !KABPrefs::instance()->mHonorSingleClick)
{
emit executed(item);
} else
emit doubleClicked(item);
}
void CardView::contentsMouseMoveEvent( QMouseEvent *e )
{
// resizing
if ( d->mResizeAnchor )
{
int x = e->x();
if ( x != d->mRubberBandAnchor )
drawRubberBands( x );
return;
}
if (d->mLastClickOnItem && (e->state() & Qt::LeftButton) &&
((e->pos() - d->mLastClickPos).manhattanLength() > 4)) {
startDrag();
return;
}
d->mTimer->start( 500 );
// see if we are over a separator
// only if we actually have them painted?
if ( d->mDrawSeparators )
{
int colcontentw = d->mItemWidth + (2*d->mItemSpacing);
int colw = colcontentw + d->mSepWidth;
int m = e->x()%colw;
if ( m >= colcontentw && m > 0 )
{
setCursor( SplitVCursor ); // Why does this fail sometimes?
d->mOnSeparator = true;
}
else
{
setCursor( ArrowCursor );
d->mOnSeparator = false;
}
}
}
void CardView::enterEvent( QEvent * )
{
d->mTimer->start( 500 );
}
void CardView::leaveEvent( QEvent * )
{
d->mTimer->stop();
if (d->mOnSeparator)
{
d->mOnSeparator = false;
setCursor( ArrowCursor );
}
}
void CardView::focusInEvent( QFocusEvent * )
{
if (!d->mCurrentItem && d->mItemList.count() )
{
setCurrentItem( d->mItemList.first() );
}
else if ( d->mCurrentItem )
{
d->mCurrentItem->repaintCard();
}
}
void CardView::focusOutEvent( QFocusEvent * )
{
if (d->mCurrentItem)
d->mCurrentItem->repaintCard();
}
void CardView::keyPressEvent( QKeyEvent *e )
{
if ( ! ( childCount() && d->mCurrentItem ) )
{
e->ignore();
return;
}
-
+ if ( mFlagBlockKeyPressed )
+ return;
+ qApp->processEvents();
+ if ( e->isAutoRepeat() && !mFlagKeyPressed ) {
+ e->accept();
+ return;
+ }
+ if (! e->isAutoRepeat() )
+ mFlagKeyPressed = true;
uint pos = d->mItemList.findRef( d->mCurrentItem );
CardViewItem *aItem = 0L; // item that gets the focus
CardViewItem *old = d->mCurrentItem;
switch ( e->key() )
{
case Key_Up:
if ( pos > 0 )
{
aItem = d->mItemList.at( pos - 1 );
setCurrentItem( aItem );
}
break;
case Key_Down:
if ( pos < d->mItemList.count() - 1 )
{
aItem = d->mItemList.at( pos + 1 );
setCurrentItem( aItem );
}
break;
case Key_Left:
{
// look for an item in the previous/next column, starting from
// the vertical middle of the current item.
// FIXME use nice calculatd measures!!!
QPoint aPoint( d->mCurrentItem->d->x, d->mCurrentItem->d->y );
aPoint -= QPoint( 30,-(d->mCurrentItem->height()/2) );
aItem = itemAt( aPoint );
// maybe we hit some space below an item
while ( !aItem && aPoint.y() > 27 )
{
aPoint -= QPoint( 0, 16 );
aItem = itemAt( aPoint );
}
if ( aItem )
setCurrentItem( aItem );
}
break;
case Key_Right:
{
// FIXME use nice calculated measures!!!
QPoint aPoint( d->mCurrentItem->d->x + d->mItemWidth, d->mCurrentItem->d->y );
aPoint += QPoint( 30,(d->mCurrentItem->height()/2) );
aItem = itemAt( aPoint );
while ( !aItem && aPoint.y() > 27 )
{
aPoint -= QPoint( 0, 16 );
aItem = itemAt( aPoint );
}
if ( aItem )
setCurrentItem( aItem );
}
break;
case Key_Home:
aItem = d->mItemList.first();
setCurrentItem( aItem );
break;
case Key_End:
aItem = d->mItemList.last();
setCurrentItem( aItem );
break;
case Key_Prior: // PageUp
{
// QListView: "Make the item above the top visible and current"
// TODO if contentsY(), pick the top item of the leftmost visible column
if ( contentsX() <= 0 )
return;
int cw = columnWidth();
int theCol = ( QMAX( 0, ( contentsX()/cw) * cw ) ) + d->mItemSpacing;
aItem = itemAt( QPoint( theCol + 1, d->mItemSpacing + 1 ) );
if ( aItem )
setCurrentItem( aItem );
}
break;
case Key_Next: // PageDown
{
// QListView: "Make the item below the bottom visible and current"
// find the first not fully visible column.
// TODO: consider if a partly visible (or even hidden) item at the
// bottom of the rightmost column exists
int cw = columnWidth();
int theCol = ( (( contentsX() + visibleWidth() )/cw) * cw ) + d->mItemSpacing + 1;
// if separators are on, we may need to we may be one column further right if only the spacing/sep is hidden
if ( d->mDrawSeparators && cw - (( contentsX() + visibleWidth() )%cw) <= int( d->mItemSpacing + d->mSepWidth ) )
theCol += cw;
// make sure this is not too far right
while ( theCol > contentsWidth() )
theCol -= columnWidth();
aItem = itemAt( QPoint( theCol, d->mItemSpacing + 1 ) );
if ( aItem )
setCurrentItem( aItem );
}
break;
case Key_Space:
setSelected( d->mCurrentItem, !d->mCurrentItem->isSelected() );
emit selectionChanged();
break;
case Key_Return:
case Key_Enter:
{
emit returnPressed( d->mCurrentItem );
emit executed( d->mCurrentItem );
}
break;
default:
if ( (e->state() & ControlButton) && e->key() == Key_A )
{
// select all
selectAll( true );
break;
}
// if we have a string, do autosearch
else if ( ! e->text().isEmpty() && e->text()[0].isPrint() )
{
}
break;
}
// handle selection
if ( aItem )
{
if ( d->mSelectionMode == CardView::Extended )
{
if ( (e->state() & ShiftButton) )
{
// shift button: toggle range
// if control button is pressed, leave all items
// and toggle selection current->old current
// otherwise, ??????
bool s = ! aItem->isSelected();
int from, to, a, b;
a = d->mItemList.findRef( aItem );
b = d->mItemList.findRef( old );
from = a < b ? a : b;
to = a > b ? a : b;
if ( to - from > 1 )
{
bool b = signalsBlocked();
blockSignals(true);
selectAll(false);
blockSignals(b);
}
//kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl;
CardViewItem *item;
for ( ; from <= to; from++ )
{
item = d->mItemList.at( from );
item->setSelected( s );
repaintItem( item );
}
emit selectionChanged();
}
else if ( (e->state() & ControlButton) )
{
// control button: do nothing
}
else
{
// no button: move selection to this item
bool b = signalsBlocked();
blockSignals(true);
selectAll(false);
blockSignals(b);
setSelected( aItem, true );
emit selectionChanged();
}
}
}
}
void CardView::contentsWheelEvent( QWheelEvent * e )
{
scrollBy(2*e->delta()/-3, 0);
}
void CardView::setLayoutDirty(bool dirty)
{
if (d->mLayoutDirty != dirty)
{
d->mLayoutDirty = dirty;
repaint();
}
}
void CardView::setDrawCardBorder(bool enabled)
{
if (enabled != d->mDrawCardBorder)
{
d->mDrawCardBorder = enabled;
repaint();
}
}
bool CardView::drawCardBorder() const
{
return d->mDrawCardBorder;
}
void CardView::setDrawColSeparators(bool enabled)
{
if (enabled != d->mDrawSeparators)
{
d->mDrawSeparators = enabled;
setLayoutDirty(true);
}
}
bool CardView::drawColSeparators() const
{
return d->mDrawSeparators;
}
void CardView::setDrawFieldLabels(bool enabled)
{
if (enabled != d->mDrawFieldLabels)
{
d->mDrawFieldLabels = enabled;
repaint();
}
}
bool CardView::drawFieldLabels() const
{
return d->mDrawFieldLabels;
}
void CardView::setShowEmptyFields(bool show)
{
if (show != d->mShowEmptyFields)
{
d->mShowEmptyFields = show;
setLayoutDirty(true);
}
}
bool CardView::showEmptyFields() const
{
return d->mShowEmptyFields;
}
void CardView::startDrag()
{
// The default implementation is a no-op. It must be
// reimplemented in a subclass to be useful
}
void CardView::tryShowFullText()
{
d->mTimer->stop();
// if we have an item
QPoint cpos = viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) );
CardViewItem *item = itemAt( cpos );
if ( item )
{
// query it for a value to display
//QString s = item ? item->caption() : "(no item)";
//kdDebug()<<"MOUSE REST: "<<s<<endl;
QPoint ipos = cpos - itemRect( item ).topLeft();
item->showFullString( ipos, d->mTip );
}
}
void CardView::drawRubberBands( int pos )
{
if ( pos && ((pos-d->firstX)/d->span) - d->colspace - d->mSepWidth < MIN_ITEM_WIDTH ) return;
int tmpcw = (d->mRubberBandAnchor-d->firstX)/d->span;
int x = d->firstX + tmpcw - d->mSepWidth - contentsX();
int h = visibleHeight();
QPainter p( viewport() );
p.setRasterOp( XorROP );
p.setPen( gray );
p.setBrush( gray );
uint n = d->first;
// erase
if ( d->mRubberBandAnchor )
do {
p.drawRect( x, 0, 2, h );
x += tmpcw;
n++;
} while ( x < visibleWidth() && n < d->mSeparatorList.count() );
// paint new
if ( ! pos ) return;
tmpcw = (pos - d->firstX)/d->span;
n = d->first;
x = d->firstX + tmpcw - d->mSepWidth - contentsX();
do {
p.drawRect( x, 0, 2, h );
x += tmpcw;
n++;
} while ( x < visibleWidth() && n < d->mSeparatorList.count() );
d->mRubberBandAnchor = pos;
}
int CardView::itemWidth() const
{
return d->mItemWidth;
}
void CardView::setItemWidth( int w )
{
if ( w == d->mItemWidth )
return;
if ( w < MIN_ITEM_WIDTH )
w = MIN_ITEM_WIDTH;
d->mItemWidth = w;
setLayoutDirty( true );
#ifndef KAB_EMBEDDED
updateContents();
#else //KAB_EMBEDDED
//US updateContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight() );
qDebug("CardView::setItemWidth has to be verified");
updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
#endif //KAB_EMBEDDED
}
void CardView::setHeaderFont( const QFont &fnt )
{
d->mHeaderFont = fnt;
delete d->mBFm;
d->mBFm = new QFontMetrics( fnt );
}
QFont CardView::headerFont() const
{
return d->mHeaderFont;
}
void CardView::setFont( const QFont &fnt )
{
QScrollView::setFont( fnt );
delete d->mFm;
d->mFm = new QFontMetrics( fnt );
}
int CardView::separatorWidth()
{
return d->mSepWidth;
}
void CardView::setSeparatorWidth( int width )
{
d->mSepWidth = width;
setLayoutDirty( true ); // hmm, actually I could just adjust the x'es...
}
int CardView::maxFieldLines() const
{
return d->mMaxFieldLines;
}
void CardView::setMaxFieldLines( int howmany )
{
d->mMaxFieldLines = howmany ? howmany : INT_MAX;
// FIXME update, forcing the items to recalc height!!
}
+
+void CardView::keyReleaseEvent ( QKeyEvent * e )
+{
+ if ( mFlagBlockKeyPressed )
+ return;
+ if ( !e->isAutoRepeat() ) {
+ mFlagBlockKeyPressed = true;
+ qApp->processEvents();
+ mFlagBlockKeyPressed = false;
+ mFlagKeyPressed = false;
+ }
+ QScrollView::keyReleaseEvent ( e );
+}
+
+
+
+
+
//END Cardview
#ifndef KAB_EMBEDDED
#include "cardview.moc"
#endif //KAB_EMBEDDED
diff --git a/kaddressbook/views/cardview.h b/kaddressbook/views/cardview.h
index 37dddb6..2ea3771 100644
--- a/kaddressbook/views/cardview.h
+++ b/kaddressbook/views/cardview.h
@@ -1,473 +1,476 @@
#ifndef CARDVIEW_H
#define CARDVIEW_H
#include <qscrollview.h>
#include <qptrlist.h>
#include <qstring.h>
#include <qrect.h>
#include <qpair.h>
#include <qpoint.h>
class QLabel;
class QPainter;
class QResizeEvent;
class QMouseEvent;
class CardView;
class CardViewPrivate;
class CardViewItemPrivate;
class CardViewTip;
/** Represents a single card (item) in the card view. A card has a caption
* and a list of fields. A Field is a label<->value pair. The labels in a
* card should be unique, since they will be used to index the values.
*/
class CardViewItem
{
friend class CardView;
public:
/** A single field in the card view. The first item is the label
* and the second item is the value.
*/
typedef QPair<QString, QString> Field;
/** Constructor.
*
* @param parent The CardView that this card should be displayed on.
* @param caption The caption of the card. This is the text that will
* appear at the top of the card. This is also the string that will
* be used to sort the cards in the view.
*/
CardViewItem(CardView *parent, QString caption = QString::null);
virtual ~CardViewItem();
/** @return The caption of the card, or QString::null if none was ever
* set.
*/
const QString &caption() const;
/** Sets the caption of the card. This is the text that will
* appear at the top of the card. This is also the string that will
* be used to sort the cards in the view.
*/
void setCaption(const QString &caption);
/** Paints the card using the given painter and color group. The
* card will handle painting itself selected if it is selected.
*/
virtual void paintCard(QPainter *p, QColorGroup &cg);
/** Repaints the card. This is done by sending a repaint event to the
* view with the clip rect defined as this card.
*/
virtual void repaintCard();
/** Adds a field to the card.
*
* @param label The label of the field. The field labels must be unique
* within a card.
* @param The value of the field.
*/
void insertField(const QString &label, const QString &value);
/** Removes the field with label <i>label</i> from the card.
*/
void removeField(const QString &label);
/** @return The value of the field with label <i>label</i>.
*/
QString fieldValue(const QString &label);
/** Removes all the fields from this card.
*/
void clearFields();
/** @return The next card item. The order of the items will be the same
* as the display order in the view. 0 will be returned if this is the
* last card.
*/
CardViewItem *nextItem();
/** @return True if this card is currently selected, false otherwise.
*/
bool isSelected() const;
/** Called by the parent card view when the mouse has been resting for
* a certain amount of time. If the label or value at pos is obscured
* (trimmed) make the label display the full text.
*/
void showFullString( const QPoint &pos, CardViewTip *tip );
/** @return a pointer to the Field at the position itempos
* in this item. 0 is returned if itempos is in the caption.
* @param itempos the position in item coordinates
*/
Field *fieldAt( const QPoint &itempos ) const;
CardView *cardView() { return mView; };
/** @return The height of this item as rendered, in pixels.
if @p allowCache is true, the item may use an internally
cached value rather than recalculating from scratch. The
argument is mainly to allow the cardView to change global settings (like
maxFieldLines) that might influence the items heights
*/
int height( bool allowCache=true ) const;
protected:
/** Sets the card as selected. This is usually only called from the
* card view.
*/
void setSelected(bool selected);
private:
/** Sets the default values.
*/
void initialize();
/** Trims a string to the width <i>width</i> using the font metrics
* to determine the width of each char. If the string is longer than
* <i>width</i>, then the string will be trimmed and a '...' will
* be appended.
*/
QString trimString(const QString &text, int width, QFontMetrics &fm);
CardViewItemPrivate *d;
CardView *mView;
};
/** The CardView is a method of displaying data in cards. This idea is
* similar to the idea of a rolodex or business cards. Each card has a
* caption and a list of fields, which are label<->value pairs. The CardView
* displays multiple cards in a grid. The Cards are sorted based on their
* caption.
*
* The CardView class is designed to mirror the API of the QListView or
* QIconView. The CardView is also completely independant of KAddressBook and
* can be used elsewhere. With the exception of a few simple config checks,
* the CardView is also 100% independant of KDE.
*/
class CardView : public QScrollView
{
friend class CardViewItem;
Q_OBJECT
public:
/** Constructor.
*/
CardView(QWidget *parent, const char *name);
virtual ~CardView();
/** Inserts the item into the card view. This method does not have
* to be called if you created the item with a proper parent. Once
* inserted, the CardView takes ownership of the item.
*/
void insertItem(CardViewItem *item);
/** Takes the item from the view. The item will not be deleted and
* ownership of the item is returned to the caller.
*/
void takeItem(CardViewItem *item);
/** Clears the view and deletes all card view items
*/
void clear();
/** @return The current item, the item that has the focus.
* Whenever the view has focus, this item has a focus rectangle painted
* at it's border.
* @sa setCurrentItem()
*/
CardViewItem *currentItem();
/** Sets the CardViewItem @p item to the current item in the view.
*/
void setCurrentItem( CardViewItem *item );
/** @return The item found at the given point, or 0 if there is no item
* at that point.
*/
CardViewItem *itemAt(const QPoint &viewPos);
/** @return The bounding rect of the given item.
*/
QRect itemRect(const CardViewItem *item);
/** Ensures that the given item is in the viewable area of the widget
*/
void ensureItemVisible(const CardViewItem *item);
/** Repaints the given item.
*/
void repaintItem(const CardViewItem *item);
enum SelectionMode { Single, Multi, Extended, NoSelection };
/** Sets the selection mode.
*
* @see QListView
*/
void setSelectionMode(SelectionMode mode);
/** @return The current selection mode.
*/
SelectionMode selectionMode() const;
/** Selects or deselects the given item. This method honors the current
* selection mode, so if other items are selected, they may be unselected.
*/
void setSelected(CardViewItem *item, bool selected);
/** Selects or deselects all items.
*/
void selectAll(bool state);
/** @return True if the given item is selected, false otherwise.
*/
bool isSelected(CardViewItem *item) const;
/** @return The first selected item. In single select mode, this will be
* the only selected item, in other modes this will be the first selected
* item, but others may exist. 0 if no item is selected.
*/
CardViewItem *selectedItem() const;
/** @return The first item in the view. This may be 0 if no items have
* been inserted. This method combined with CardViewItem::nextItem()
* can be used to iterator through the list of items.
*/
CardViewItem *firstItem() const;
/** @return The item after the given item or 0 if the item is the last
* item.
*/
CardViewItem *itemAfter(CardViewItem *item);
/** @return The number of items in the view.
*/
int childCount() const;
/** Attempts to find the first item matching the params.
*
* @param text The text to match.
* @param label The label of the field to match against.
* @param compare The compare method to use in doing the search.
*
* @return The first matching item, or 0 if no items match.
*/
/*US
CardViewItem *findItem(const QString &text, const QString &label,
Qt::StringComparisonMode compare = Qt::BeginsWith);
*/
/** Returns the amounts of pixels required for one column.
* This depends on wheather drawSeparators is enabled:
* If so, it is itemWidth + 2*itemSpacing + separatorWidth
* If not, it is itemWidth + itemSpacing
* @see itemWidth(), setItemWidth(), itemSpacing() and setItemSpacing()
*/
uint columnWidth();
/** Sets if the border around a card should be draw. The border is a thing
* (1 or 2 pixel) line that bounds the card. When drawn, it shows when
* a card is highlighted and when it isn't.
*/
void setDrawCardBorder(bool enabled);
/** @return True if borders are drawn, false otherwise.
*/
bool drawCardBorder() const;
/** Sets if the column separator should be drawn. The column separator
* is a thin verticle line (1 or 2 pixels) that is used to separate the
* columns in the list view. The separator is just for esthetics and it
* does not serve a functional purpose.
*/
void setDrawColSeparators(bool enabled);
/** @return True if column separators are drawn, false otherwise.
*/
bool drawColSeparators() const;
/** Sets if the field labels should be drawn. The field labels are the
* unique strings used to identify the fields. Sometimes drawing these
* labels makes sense as a source of clarity for the user, othertimes they
* waste too much space and do not assist the user.
*/
void setDrawFieldLabels(bool enabled);
/** @return True if the field labels are drawn, false otherwise.
*/
bool drawFieldLabels() const;
/** Sets if fields with no value should be drawn (of cause the label only,
* but it allows for embedded editing sometimes...)
*/
void setShowEmptyFields(bool show);
/** @return Wheather empty fields should be shown
*/
bool showEmptyFields() const;
/** @return the advisory internal margin in items. Setting a value above 1 means
* a space between the item contents and the focus recttangle drawn around
* the current item. The default value is 0.
* The value should be used by CardViewItem and derived classes.
* Note that this should not be greater than half of the minimal item width,
* which is 80. It is currently not checked, so setting a value greater than 40
* will probably mean a crash in the items painting routine.
* @private Note: I looked for a value in QStyle::PixelMetric to use, but I could
* not see a usefull one. One may turn up in a future version of Qt.
*/
uint itemMargin();
/** Sets the internal item margin. @see itemMargin().
*/
void setItemMargin( uint margin );
/** @return the item spacing.
* The item spacing is the space (in pixels) between each item in a
* column, between the items and column separators if drawn, and between
* the items and the borders of the widget. The default value is set to
* 10.
* @private Note: There is no usefull QStyle::PixelMetric to use for this atm.
* An option would be using KDialog::spacingHint().
*/
uint itemSpacing();
/** Sets the item spacing.
* @see itemSpacing()
*/
void setItemSpacing( uint spacing );
/** @return the width made available to the card items. */
int itemWidth() const;
/** Sets the width made available to card items. */
void setItemWidth( int width );
/** Sets the header font */
void setHeaderFont( const QFont &fnt );
/** @return the header font */
QFont headerFont() const;
/** @reimp */
void setFont( const QFont &fnt );
/** Sets the column separator width */
void setSeparatorWidth( int width );
/** @return the column separator width */
int separatorWidth();
/** Sets the maximum number of lines to display pr field.
If set to 0 (the default) all lines will be displayed.
*/
void setMaxFieldLines( int howmany );
/** @return the maximum number of lines pr field */
int maxFieldLines() const;
signals:
/** Emitted whenever the selection changes. This means a user highlighted
* a new item or unhighlighted a currently selected item.
*/
void selectionChanged();
/** Same as above method, only it carries the item that was selected. This
* method will only be emitted in single select mode, since it defineds
* which item was selected.
*/
void selectionChanged(CardViewItem *);
/** This method is emitted whenever an item is clicked.
*/
void clicked(CardViewItem *);
/** Emitted whenever the user 'executes' an item. This is dependant on
* the KDE global config. This could be a single click or a doubleclick.
* Also emitted when the return key is pressed on an item.
*/
void executed(CardViewItem *);
/** Emitted whenever the user double clicks on an item.
*/
void doubleClicked(CardViewItem *);
/** Emitted when the current item changes
*/
void currentChanged( CardViewItem * );
/** Emitted when the return key is pressed in an item.
*/
void returnPressed( CardViewItem * );
- protected:
+ protected:
+ bool mFlagKeyPressed;
+ bool mFlagBlockKeyPressed;
+ virtual void keyPressEvent ( QKeyEvent * );
+ virtual void keyReleaseEvent ( QKeyEvent * );
/** Determines which cards intersect that region and tells them to paint
* themselves.
*/
void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph);
/** Sets the layout to dirty and repaints.
*/
void resizeEvent(QResizeEvent *e);
/** Changes the direction the canvas scolls.
*/
void contentsWheelEvent(QWheelEvent *e);
/** Sets the layout to dirty and calls for a repaint.
*/
void setLayoutDirty(bool dirty);
/** Does the math based on the bounding rect of the cards to properly
* lay the cards out on the screen. This is only done if the layout is
* marked as dirty.
*/
void calcLayout();
// virtual void mousePressEvent(QMouseEvent *e);
// virtual void mouseReleaseEvent(QMouseEvent *e);
// virtual void mouseMoveEvent(QMouseEvent *e);
virtual void contentsMousePressEvent(QMouseEvent *e);
virtual void contentsMouseMoveEvent(QMouseEvent *e);
virtual void contentsMouseReleaseEvent(QMouseEvent *e);
virtual void contentsMouseDoubleClickEvent(QMouseEvent *e);
virtual void enterEvent( QEvent * );
virtual void leaveEvent( QEvent * );
virtual void focusInEvent( QFocusEvent * );
virtual void focusOutEvent( QFocusEvent * );
- virtual void keyPressEvent( QKeyEvent * );
/** Overload this method to be told when a drag should be started.
* In most cases you will want to start a drag event with the currently
* selected item.
*/
virtual void startDrag();
private slots:
/** Called by a timer to display a label with truncated text.
* Pop up a label, if there is a field with obscured text or
* label at the cursor position.
*/
void tryShowFullText();
private:
/** draws and erases the rubber bands while columns are resized.
* @p pos is the horizontal position inside the viewport to use as
* the anchor.
* If pos is 0, only erase is done.
*/
void drawRubberBands( int pos );
CardViewPrivate *d;
};
#endif
diff --git a/kaddressbook/views/contactlistview.cpp b/kaddressbook/views/contactlistview.cpp
index e75810e..09d9c03 100644
--- a/kaddressbook/views/contactlistview.cpp
+++ b/kaddressbook/views/contactlistview.cpp
@@ -1,400 +1,429 @@
/*
This file is part of KAddressBook.
Copyright (c) 2002 Mike Pilone <mpilone@slac.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <qheader.h>
#include <qiconset.h>
#include <qimage.h>
#include <qdragobject.h>
#include <qcombobox.h>
#include <qpainter.h>
#include <qbrush.h>
#include <qevent.h>
+#include <qapplication.h>
#include <klocale.h>
#include <kglobalsettings.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <kconfig.h>
#include <kapplication.h>
#include <kurl.h>
#include "kaddressbooktableview.h"
#include "contactlistview.h"
/////////////////////////////////
// DynamicTip Methods
DynamicTip::DynamicTip( ContactListView *parent)
: QToolTip( parent )
{
}
void DynamicTip::maybeTip( const QPoint &pos )
{
static bool ishidden = true;
if (!parentWidget()->inherits( "ContactListView" ))
return;
ContactListView *plv = (ContactListView*)parentWidget();
if (!plv->tooltips())
return;
QPoint posVp = plv->viewport()->pos();
QListViewItem *lvi = plv->itemAt( pos - posVp );
if (!lvi)
return;
#ifndef KAB_EMBEDDED
ContactListViewItem *plvi = dynamic_cast< ContactListViewItem* >(lvi);
#else //KAB_EMBEDDED
ContactListViewItem *plvi = (ContactListViewItem*)(lvi);
#endif //KAB_EMBEDDED
if (!plvi)
return;
if (ishidden) {
QString s;
QRect r = plv->itemRect( lvi );
r.moveBy( posVp.x(), posVp.y() );
//kdDebug() << "Tip rec: " << r.x() << "," << r.y() << "," << r.width()
// << "," << r.height() << endl;
KABC::Addressee a = plvi->addressee();
if (a.isEmpty())
return;
s += i18n("label: value", "%1: %2").arg(a.formattedNameLabel())
.arg(a.formattedName());
s += '\n';
s += i18n("label: value", "%1: %2").arg(a.organizationLabel())
.arg(a.organization());
QString notes = a.note().stripWhiteSpace();
if ( !notes.isEmpty() ) {
notes += '\n';
s += '\n' + i18n("label: value", "%1: \n").arg(a.noteLabel());
QFontMetrics fm( font() );
// Begin word wrap code based on QMultiLineEdit code
int i = 0;
bool doBreak = false;
int linew = 0;
int lastSpace = -1;
int a = 0;
int lastw = 0;
while ( i < int(notes.length()) ) {
doBreak = FALSE;
if ( notes[i] != '\n' )
linew += fm.width( notes[i] );
if ( lastSpace >= a && notes[i] != '\n' )
if (linew >= parentWidget()->width()) {
doBreak = TRUE;
if ( lastSpace > a ) {
i = lastSpace;
linew = lastw;
}
else
i = QMAX( a, i-1 );
}
if ( notes[i] == '\n' || doBreak ) {
s += notes.mid( a, i - a + (doBreak?1:0) ) +"\n";
a = i + 1;
lastSpace = a;
linew = 0;
}
if ( notes[i].isSpace() ) {
lastSpace = i;
lastw = linew;
}
if ( lastSpace <= a ) {
lastw = linew;
}
++i;
}
}
tip( r, s );
}
else
hide();
ishidden = !ishidden;
}
///////////////////////////
// ContactListViewItem Methods
ContactListViewItem::ContactListViewItem(const KABC::Addressee &a,
ContactListView *parent,
KABC::AddressBook *doc,
const KABC::Field::List &fields )
: KListViewItem(parent), mAddressee(a), mFields( fields ),
parentListView( parent ), mDocument(doc)
{
refresh();
}
QString ContactListViewItem::key(int column, bool ascending) const
{
#ifndef DESKTOP_VERSION
int lan = KGlobal::locale()->language();
//qDebug("language %d ", lan);
if ( lan == 1 ) { //GERMAN
QString ret = QListViewItem::key(column, ascending).lower().utf8();
int start = -1;
while ( (start = ret.find( 'ä', start+1)) > 0 ) {
ret.at(start-1) = 'a';
}
start = -1;
while ( (start = ret.find( 'ö', start+1)) > 0 ) {
ret.at(start-1) = 'o';
}
start = -1;
while ( (start = ret.find( 'ü', start+1)) > 0 ) {
ret.at(start-1) = 'o';
}
start = -1;
while ( (start = ret.find( 'ß', start+1)) > 0 ) {
ret.at(start-1) = 's';
}
//qDebug("conv string %s ", ret.latin1());
return ret;
}
else
#endif
return QListViewItem::key(column, ascending).lower();
}
void ContactListViewItem::paintCell(QPainter * p,
const QColorGroup & cg,
int column,
int width,
int align)
{
KListViewItem::paintCell(p, cg, column, width, align);
if ( !p )
return;
if (parentListView->singleLine()) {
p->setPen( parentListView->alternateColor() );
p->drawLine( 0, height() - 1, width, height() - 1 );
}
}
ContactListView *ContactListViewItem::parent()
{
return parentListView;
}
void ContactListViewItem::refresh()
{
// Update our addressee, since it may have changed else were
mAddressee = mDocument->findByUid(mAddressee.uid());
if (mAddressee.isEmpty())
return;
int i = 0;
KABC::Field::List::ConstIterator it;
for( it = mFields.begin(); it != mFields.end(); ++it ) {
setText( i++, (*it)->value( mAddressee ) );
}
}
///////////////////////////////
// ContactListView
ContactListView::ContactListView(KAddressBookTableView *view,
KABC::AddressBook* /* doc */,
QWidget *parent,
const char *name )
: KListView( parent, name ),
pabWidget( view ),
oldColumn( 0 )
{
+ mFlagBlockKeyPressed = false;
+ mFlagKeyPressed = false;
mABackground = true;
mSingleLine = false;
mToolTips = true;
#ifndef KAB_EMBEDDED
mAlternateColor = KGlobalSettings::alternateBackgroundColor();
#else //KAB_EMBEDDED
mAlternateColor = QColor(240, 240, 240);
#endif //KAB_EMBEDDED
setAlternateBackgroundEnabled(mABackground);
setAcceptDrops( true );
viewport()->setAcceptDrops( true );
setAllColumnsShowFocus( true );
setShowSortIndicator(true);
setSelectionModeExt( KListView::Extended );
setDropVisualizer(false);
// setFrameStyle(QFrame::NoFrame);
//setLineWidth ( 0 );
//setMidLineWidth ( 0 );
//setMargin ( 0 );
#ifndef KAB_EMBEDDED
connect(this, SIGNAL(dropped(QDropEvent*)),
this, SLOT(itemDropped(QDropEvent*)));
#endif //KAB_EMBEDDED
new DynamicTip( this );
}
void ContactListView::printMe()
{
#ifdef DESKTOP_VERSION
QPrinter printer;
if (!printer.setup() )
return;
QPainter p;
p.begin ( &printer );
QPaintDeviceMetrics m = QPaintDeviceMetrics ( &printer );
float dx, dy;
int wid = (m.width() * 9)/10;
dx = (float) wid/(float)contentsWidth ();
dy = (float)(m.height()) / (float)contentsHeight ();
float scale;
// scale to fit the width or height of the paper
if ( dx < dy )
scale = dx;
else
scale = dy;
p.translate( m.width()/10,0 );
p.scale( scale, scale );
qDebug("scale %f ", scale);
drawContents ( &p, 0,0, contentsWidth (), contentsHeight () );
p.end();
qDebug("Why does it not print??? ");
#endif
}
void ContactListView::setAlternateColor(const QColor &m_AlternateColor)
{
mAlternateColor = m_AlternateColor;
}
void ContactListView::paintEmptyArea( QPainter * p, const QRect & rect )
{
QBrush b = palette().brush(QPalette::Active, QColorGroup::Base);
// Get the brush, which will have the background pixmap if there is one.
if (b.pixmap())
{
p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(),
*(b.pixmap()),
rect.left() + contentsX(),
rect.top() + contentsY() );
}
else
{
// Do a normal paint
KListView::paintEmptyArea(p, rect);
}
}
void ContactListView::contentsMousePressEvent(QMouseEvent* e)
{
presspos = e->pos();
KListView::contentsMousePressEvent(e);
}
// To initiate a drag operation
void ContactListView::contentsMouseMoveEvent( QMouseEvent *e )
{
if ((e->state() & LeftButton) && (e->pos() - presspos).manhattanLength() > 4 ) {
emit startAddresseeDrag();
}
else
KListView::contentsMouseMoveEvent( e );
}
bool ContactListView::acceptDrag(QDropEvent *e) const
{
#ifndef KAB_EMBEDDED
return QTextDrag::canDecode(e);
#else //KAB_EMBEDDED
qDebug("ContactListView::acceptDrag has to be fixed");
return false;
#endif //KAB_EMBEDDED
}
void ContactListView::itemDropped(QDropEvent *e)
{
contentsDropEvent(e);
}
void ContactListView::contentsDropEvent( QDropEvent *e )
{
emit addresseeDropped(e);
}
void ContactListView::setAlternateBackgroundEnabled(bool enabled)
{
mABackground = enabled;
if (mABackground)
{
setAlternateBackground(mAlternateColor);
}
else
{
setAlternateBackground(QColor());
}
}
void ContactListView::setBackgroundPixmap(const QString &filename)
{
if (filename.isEmpty())
{
unsetPalette();
}
else
{
qDebug("ContactListView::setBackgroundPixmap has to be verified");
//US setPaletteBackgroundPixmap(QPixmap(filename));
KListView::setBackgroundPixmap((const QPixmap&)QPixmap(filename));
}
}
+
+void ContactListView::keyPressEvent ( QKeyEvent * e )
+{
+ if ( mFlagBlockKeyPressed )
+ return;
+ qApp->processEvents();
+ if ( e->isAutoRepeat() && !mFlagKeyPressed ) {
+ e->accept();
+ return;
+ }
+ if (! e->isAutoRepeat() )
+ mFlagKeyPressed = true;
+ KListView::keyPressEvent ( e );
+}
+void ContactListView::keyReleaseEvent ( QKeyEvent * e )
+{
+ if ( mFlagBlockKeyPressed )
+ return;
+ if ( !e->isAutoRepeat() ) {
+ mFlagBlockKeyPressed = true;
+ qApp->processEvents();
+ mFlagBlockKeyPressed = false;
+ mFlagKeyPressed = false;
+ }
+ KListView::keyReleaseEvent ( e );
+}
#ifndef KAB_EMBEDDED
#include "contactlistview.moc"
#endif //KAB_EMBEDDED
diff --git a/kaddressbook/views/contactlistview.h b/kaddressbook/views/contactlistview.h
index 9d1a672..46477e1 100644
--- a/kaddressbook/views/contactlistview.h
+++ b/kaddressbook/views/contactlistview.h
@@ -1,130 +1,134 @@
#ifndef CONTACTLISTVIEW_H
#define CONTACTLISTVIEW_H
#include <qcolor.h>
#include <qpixmap.h>
#include <qtooltip.h>
#include <qstring.h>
#include <klistview.h>
#include <kabc/field.h>
#include <kabc/addressee.h>
#include <kabc/addressbook.h>
class QDropEvent;
class KAddressBookTableView;
class ContactListView;
/** The whole tooltip design needs a lot of work. Currently it is
* hacked together to function.
*/
class DynamicTip : public QToolTip
{
public:
DynamicTip( ContactListView * parent );
protected:
void maybeTip( const QPoint & );
private:
};
class ContactListViewItem : public KListViewItem
{
public:
ContactListViewItem(const KABC::Addressee &a, ContactListView* parent,
KABC::AddressBook *doc, const KABC::Field::List &fields );
const KABC::Addressee &addressee() const { return mAddressee; }
virtual void refresh();
virtual ContactListView* parent();
virtual QString key ( int, bool ) const;
/** Adds the border around the cell if the user wants it.
* This is how the single line config option is implemented.
*/
virtual void paintCell(QPainter * p, const QColorGroup & cg,
int column, int width, int align );
private:
KABC::Addressee mAddressee;
KABC::Field::List mFields;
ContactListView *parentListView;
KABC::AddressBook *mDocument;
};
/////////////////////////////////////////////
// ContactListView
class ContactListView : public KListView
{
Q_OBJECT
public:
ContactListView(KAddressBookTableView *view,
KABC::AddressBook *doc,
QWidget *parent,
const char *name = 0L );
virtual ~ContactListView() {}
//void resort();
/** Returns true if tooltips should be displayed, false otherwise
*/
bool tooltips() const { return mToolTips; }
void setToolTipsEnabled(bool enabled) { mToolTips = enabled; }
bool alternateBackground() const { return mABackground; }
void setAlternateBackgroundEnabled(bool enabled);
bool singleLine() const { return mSingleLine; }
void setSingleLineEnabled(bool enabled) { mSingleLine = enabled; }
const QColor &alternateColor() const { return mAlternateColor; }
void setAlternateColor(const QColor &mAlternateColor);
/** Sets the background pixmap to <i>filename</i>. If the
* QString is empty (QString::isEmpty()), then the background
* pixmap will be disabled.
*/
void setBackgroundPixmap(const QString &filename);
protected:
+ bool mFlagKeyPressed;
+ bool mFlagBlockKeyPressed;
+ virtual void keyPressEvent ( QKeyEvent * );
+ virtual void keyReleaseEvent ( QKeyEvent * );
/** Paints the background pixmap in the empty area. This method is needed
* since Qt::FixedPixmap will not scroll with the list view.
*/
virtual void paintEmptyArea( QPainter * p, const QRect & rect );
virtual void contentsMousePressEvent(QMouseEvent*);
void contentsMouseMoveEvent( QMouseEvent *e );
void contentsDropEvent( QDropEvent *e );
virtual bool acceptDrag(QDropEvent *e) const;
protected slots:
void itemDropped(QDropEvent *e);
public slots:
void printMe();
signals:
void startAddresseeDrag();
void addresseeDropped(QDropEvent *);
private:
KAddressBookTableView *pabWidget;
int oldColumn;
int column;
bool ascending;
bool mABackground;
bool mSingleLine;
bool mToolTips;
QColor mAlternateColor;
QPoint presspos;
};
#endif
diff --git a/kaddressbook/views/kaddressbookcardview.cpp b/kaddressbook/views/kaddressbookcardview.cpp
index cce68b9..9c35fd6 100644
--- a/kaddressbook/views/kaddressbookcardview.cpp
+++ b/kaddressbook/views/kaddressbookcardview.cpp
@@ -1,503 +1,507 @@
/*
This file is part of KAddressBook.
Copyright (c) 2002 Mike Pilone <mpilone@slac.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <qdragobject.h>
#include <qevent.h>
#include <qiconview.h>
#include <qlayout.h>
#include <qstringlist.h>
#include <qregexp.h>
#include <qapplication.h>
#include <kabc/addressbook.h>
#include <kabc/addressee.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include "kabprefs.h"
#include "viewmanager.h"
#include "kaddressbookcardview.h"
#ifndef KAB_EMBEDDED
extern "C" {
void *init_libkaddrbk_cardview()
{
return ( new CardViewFactory );
}
}
#endif //KAB_EMBEDDED
////////////////////////////////
// AddresseeCardViewItem (internal class)
class AddresseeCardViewItem : public CardViewItem
{
public:
AddresseeCardViewItem(const KABC::Field::List &fields,
bool showEmptyFields,
KABC::AddressBook *doc, const KABC::Addressee &a,
CardView *parent)
: CardViewItem(parent, a.realName() ),
mFields( fields ), mShowEmptyFields(showEmptyFields),
mDocument(doc), mAddressee(a)
{
if ( mFields.isEmpty() ) {
mFields = KABC::Field::defaultFields();
}
refresh();
}
const KABC::Addressee &addressee() const { return mAddressee; }
void refresh()
{
// Update our addressee, since it may have changed elsewhere
mAddressee = mDocument->findByUid(mAddressee.uid());
if (!mAddressee.isEmpty())
{
clearFields();
// Try all the selected fields until we find one with text.
// This will limit the number of unlabeled icons in the view
KABC::Field::List::Iterator iter;
for (iter = mFields.begin(); iter != mFields.end(); ++iter)
{
// insert empty fields or not? not doing so saves a bit of memory and CPU
// (during geometry calculations), but prevents having equally
// wide label columns in all cards, unless CardViewItem/CardView search
// globally for the widest label. (anders)
//if (mShowEmptyFields || !(*iter)->value( mAddressee ).isEmpty())
insertField((*iter)->label(), (*iter)->value( mAddressee ));
}
// We might want to make this the first field. hmm... -mpilone
setCaption( mAddressee.realName() );
}
}
private:
KABC::Field::List mFields;
bool mShowEmptyFields;
KABC::AddressBook *mDocument;
KABC::Addressee mAddressee;
};
///////////////////////////////
// AddresseeCardView
AddresseeCardView::AddresseeCardView(QWidget *parent, const char *name)
: CardView(parent, name)
{
setAcceptDrops(true);
}
AddresseeCardView::~AddresseeCardView()
{
}
void AddresseeCardView::printMe()
{
#ifdef DESKTOP_VERSION
QPrinter printer;
if (!printer.setup() )
return;
QPainter p;
p.begin ( &printer );
QPaintDeviceMetrics m = QPaintDeviceMetrics ( &printer );
float dx, dy;
int wid = (m.width() * 9)/10;
dx = (float) wid/(float)contentsWidth ();
dy = (float)(m.height()) / (float)contentsHeight ();
float scale;
// scale to fit the width or height of the paper
if ( dx < dy )
scale = dx;
else
scale = dy;
p.translate( m.width()/10,0 );
p.scale( scale, scale );
drawContents ( &p, 0,0, contentsWidth (), contentsHeight () );
p.end();
repaint();
#endif
}
void AddresseeCardView::dragEnterEvent(QDragEnterEvent *e)
{
#ifndef KAB_EMBEDDED
if (QTextDrag::canDecode(e))
e->accept();
#else //KAB_EMBEDDED
qDebug("AddresseeCardView::dragEnterEvent drag&drop is not implemented");
#endif //KAB_EMBEDDED
}
void AddresseeCardView::dropEvent(QDropEvent *e)
{
emit addresseeDropped(e);
}
void AddresseeCardView::startDrag()
{
emit startAddresseeDrag();
}
///////////////////////////////
// KAddressBookCardView
KAddressBookCardView::KAddressBookCardView( KABC::AddressBook *ab,
QWidget *parent, const char *name )
: KAddressBookView( ab, parent, name )
{
mShowEmptyFields = false;
// Init the GUI
QVBoxLayout *layout = new QVBoxLayout(viewWidget());
mCardView = new AddresseeCardView(viewWidget(), "mCardView");
mCardView->setSelectionMode(CardView::Extended);
layout->addWidget(mCardView);
// Connect up the signals
connect(mCardView, SIGNAL(executed(CardViewItem *)),
this, SLOT(addresseeExecuted(CardViewItem *)));
connect(mCardView, SIGNAL(selectionChanged()),
this, SLOT(addresseeSelected()));
connect(mCardView, SIGNAL(addresseeDropped(QDropEvent*)),
this, SIGNAL(dropped(QDropEvent*)));
connect(mCardView, SIGNAL(startAddresseeDrag()),
this, SIGNAL(startDrag()));
connect(this, SIGNAL(printView()),
mCardView , SLOT(printMe()));
}
KAddressBookCardView::~KAddressBookCardView()
{
}
void KAddressBookCardView::setFocusAV()
{
if ( mCardView )
mCardView->setFocus();
}
void KAddressBookCardView::scrollUP()
{
QKeyEvent * ev = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Up, 0,0 );
QApplication::postEvent( mCardView, ev );
+ ev = new QKeyEvent ( QEvent::KeyRelease, Qt::Key_Up, 0,0 );
+ QApplication::postEvent( mCardView, ev );
}
void KAddressBookCardView::scrollDOWN()
{
QKeyEvent * ev = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Down, 0,0 );
QApplication::postEvent( mCardView, ev );
+ ev = new QKeyEvent ( QEvent::KeyRelease, Qt::Key_Down, 0,0 );
+ QApplication::postEvent( mCardView, ev );
}
void KAddressBookCardView::readConfig(KConfig *config)
{
KAddressBookView::readConfig(config);
// costum colors?
if ( config->readBoolEntry( "EnableCustomColors", false ) )
{
QPalette p( mCardView->palette() );
QColor c = p.color(QPalette::Normal, QColorGroup::Base );
p.setColor( QPalette::Normal, QColorGroup::Base, config->readColorEntry( "BackgroundColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::Text );
p.setColor( QPalette::Normal, QColorGroup::Text, config->readColorEntry( "TextColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::Button );
p.setColor( QPalette::Normal, QColorGroup::Button, config->readColorEntry( "HeaderColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::ButtonText );
p.setColor( QPalette::Normal, QColorGroup::ButtonText, config->readColorEntry( "HeaderTextColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::Highlight );
p.setColor( QPalette::Normal, QColorGroup::Highlight, config->readColorEntry( "HighlightColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::HighlightedText );
p.setColor( QPalette::Normal, QColorGroup::HighlightedText, config->readColorEntry( "HighlightedTextColor", &c ) );
mCardView->viewport()->setPalette( p );
}
else
{
// needed if turned off during a session.
mCardView->viewport()->setPalette( mCardView->palette() );
}
//custom fonts?
QFont f( font() );
if ( config->readBoolEntry( "EnableCustomFonts", false ) )
{
mCardView->setFont( config->readFontEntry( "TextFont", &f) );
f.setBold( true );
mCardView->setHeaderFont( config->readFontEntry( "HeaderFont", &f ) );
}
else
{
mCardView->setFont( f );
f.setBold( true );
mCardView->setHeaderFont( f );
}
mCardView->setDrawCardBorder(config->readBoolEntry("DrawBorder", true));
mCardView->setDrawColSeparators(config->readBoolEntry("DrawSeparators",
true));
mCardView->setDrawFieldLabels(config->readBoolEntry("DrawFieldLabels",false));
mShowEmptyFields = config->readBoolEntry("ShowEmptyFields", false);
mCardView->setShowEmptyFields( mShowEmptyFields );
mCardView->setItemWidth( config->readNumEntry( "ItemWidth", 200 ) );
mCardView->setItemMargin( config->readNumEntry( "ItemMargin", 0 ) );
mCardView->setItemSpacing( config->readNumEntry( "ItemSpacing", 10 ) );
mCardView->setSeparatorWidth( config->readNumEntry( "SeparatorWidth", 2 ) );
#if 0
// LR KABPrefs::instance()->mHonorSingleClick is handled and fixed in cardviews contentsMouseDoubleClickEven
disconnect(mCardView, SIGNAL(executed(CardViewItem *)),
this, SLOT(addresseeExecuted(CardViewItem *)));
if (KABPrefs::instance()->mHonorSingleClick)
connect(mCardView, SIGNAL(executed(CardViewItem *)),
this, SLOT(addresseeExecuted(CardViewItem *)));
else
connect(mCardView, SIGNAL(doubleClicked(CardViewItem *)),
this, SLOT(addresseeExecuted(CardViewItem *)));
#endif
connect(mCardView, SIGNAL(doubleClicked(CardViewItem *)),
this, SLOT(addresseeExecuted(CardViewItem *)));
}
void KAddressBookCardView::writeConfig( KConfig *config )
{
config->writeEntry( "ItemWidth", mCardView->itemWidth() );
KAddressBookView::writeConfig( config );
}
void KAddressBookCardView::doSearch( const QString& s,KABC::Field *field )
{
mCardView->clear();
if ( s.isEmpty() || s == "*" ) {
refresh();
return;
}
QRegExp re = getRegExp( s );
if (!re.isValid())
return;
mCardView->viewport()->setUpdatesEnabled( false );
KABC::Addressee::List addresseeList = addressees();
KABC::Addressee::List::Iterator it;
if ( field ) {
for (it = addresseeList.begin(); it != addresseeList.end(); ++it ) {
if ( (*it).uid().left(2) == "la" && (*it).uid().left(19) == QString("last-syncAddressee-") )
continue;
#if QT_VERSION >= 0x030000
if (re.search(field->value( *it ).lower()) != -1)
#else
if (re.match(field->value( *it ).lower()) != -1)
#endif
new AddresseeCardViewItem(fields(), mShowEmptyFields,
addressBook(), *it, mCardView);
}
} else {
KABC::Field::List fieldList = allFields();
KABC::Field::List::ConstIterator fieldIt;
for (it = addresseeList.begin(); it != addresseeList.end(); ++it ) {
if ( (*it).uid().left(2) == "la" && (*it).uid().left(19) == QString("last-syncAddressee-") )
continue;
for ( fieldIt = fieldList.begin(); fieldIt != fieldList.end(); ++fieldIt ) {
#if QT_VERSION >= 0x030000
if (re.search((*fieldIt)->value( *it ).lower()) != -1)
#else
if (re.match((*fieldIt)->value( *it ).lower()) != -1)
#endif
{
new AddresseeCardViewItem(fields(), mShowEmptyFields,
addressBook(), *it, mCardView);
break;
}
}
}
}
mCardView->viewport()->setUpdatesEnabled( true );
mCardView->viewport()->update();
if ( mCardView->firstItem() ) {
mCardView->setCurrentItem ( mCardView->firstItem() );
mCardView->setSelected ( mCardView->firstItem() , true );
}
else
emit selected(QString::null);
}
QStringList KAddressBookCardView::selectedUids()
{
QStringList uidList;
CardViewItem *item;
AddresseeCardViewItem *aItem;
for (item = mCardView->firstItem(); item; item = item->nextItem())
{
if (item->isSelected())
{
#ifndef KAB_EMBEDDED
aItem = dynamic_cast<AddresseeCardViewItem*>(item);
#else //KAB_EMBEDDED
aItem = (AddresseeCardViewItem*)(item);
#endif //KAB_EMBEDDED
if (aItem)
uidList << aItem->addressee().uid();
}
}
return uidList;
}
void KAddressBookCardView::refresh(QString uid)
{
CardViewItem *item;
AddresseeCardViewItem *aItem;
if (uid.isNull())
{
// Rebuild the view
mCardView->viewport()->setUpdatesEnabled( false );
mCardView->clear();
KABC::Addressee::List addresseeList = addressees();
KABC::Addressee::List::Iterator iter;
for (iter = addresseeList.begin(); iter != addresseeList.end(); ++iter)
{
if ( (*iter).uid().left(2) == "la" && (*iter).uid().left(19) == QString("last-syncAddressee-") )
continue;
aItem = new AddresseeCardViewItem(fields(), mShowEmptyFields,
addressBook(), *iter, mCardView);
}
mCardView->viewport()->setUpdatesEnabled( true );
mCardView->viewport()->update();
// by default nothing is selected
emit selected(QString::null);
}
else
{
// Try to find the one to refresh
bool found = false;
for (item = mCardView->firstItem(); item && !found;
item = item->nextItem())
{
#ifndef KAB_EMBEDDED
aItem = dynamic_cast<AddresseeCardViewItem*>(item);
#else //KAB_EMBEDDED
aItem = (AddresseeCardViewItem*)(item);
#endif //KAB_EMBEDDED
if ((aItem) && (aItem->addressee().uid() == uid))
{
aItem->refresh();
found = true;
}
}
}
}
void KAddressBookCardView::setSelected(QString uid, bool selected)
{
CardViewItem *item;
AddresseeCardViewItem *aItem;
if (uid.isNull())
{
mCardView->selectAll(selected);
}
else
{
bool found = false;
for (item = mCardView->firstItem(); item && !found;
item = item->nextItem())
{
#ifndef KAB_EMBEDDED
aItem = dynamic_cast<AddresseeCardViewItem*>(item);
#else //KAB_EMBEDDED
aItem = (AddresseeCardViewItem*)(item);
#endif //KAB_EMBEDDED
if ((aItem) && (aItem->addressee().uid() == uid))
{
mCardView->setSelected(aItem, selected);
mCardView->ensureItemVisible(item);
found = true;
}
}
}
}
//US added an additional method without parameter
void KAddressBookCardView::setSelected()
{
setSelected(QString::null, true);
}
void KAddressBookCardView::addresseeExecuted(CardViewItem *item)
{
#ifndef KAB_EMBEDDED
AddresseeCardViewItem *aItem = dynamic_cast<AddresseeCardViewItem*>(item);
#else //KAB_EMBEDDED
AddresseeCardViewItem *aItem = (AddresseeCardViewItem*)(item);
#endif //KAB_EMBEDDED
if (aItem)
{
//kdDebug()<<"... even has a valid item:)"<<endl;
emit executed(aItem->addressee().uid());
}
}
void KAddressBookCardView::addresseeSelected()
{
CardViewItem *item;
AddresseeCardViewItem *aItem;
bool found = false;
for (item = mCardView->firstItem(); item && !found;
item = item->nextItem())
{
if (item->isSelected())
{
#ifndef KAB_EMBEDDED
aItem = dynamic_cast<AddresseeCardViewItem*>(item);
#else //KAB_EMBEDDED
aItem = (AddresseeCardViewItem*)(item);
#endif //KAB_EMBEDDED
if ( aItem )
{
emit selected(aItem->addressee().uid());
found = true;
}
}
}
if (!found)
emit selected(QString::null);
}
#ifndef KAB_EMBEDDED
#include "kaddressbookcardview.moc"
#endif //KAB_EMBEDDED
diff --git a/kaddressbook/views/kaddressbooktableview.cpp b/kaddressbook/views/kaddressbooktableview.cpp
index f4b008c..e322473 100644
--- a/kaddressbook/views/kaddressbooktableview.cpp
+++ b/kaddressbook/views/kaddressbooktableview.cpp
@@ -1,470 +1,474 @@
// $Id$
#include <qvbox.h>
#include <qlistbox.h>
#include <qwidget.h>
#include <qfile.h>
#include <qimage.h>
#include <qcombobox.h>
#include <qapplication.h>
#include <qdragobject.h>
#include <qevent.h>
#include <qurl.h>
#include <qpixmap.h>
#include <kabc/addressbook.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kcolorbutton.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kurlrequester.h>
//US#include "configuretableviewdialog.h"
#include "contactlistview.h"
#include "kabprefs.h"
#include "undocmds.h"
#include "viewmanager.h"
#include <qlayout.h>
#include <qheader.h>
#include <qregexp.h>
#include "kaddressbooktableview.h"
KAddressBookTableView::KAddressBookTableView( KABC::AddressBook *ab,
QWidget *parent, const char *name )
: KAddressBookView( ab, parent, name )
{
mainLayout = new QVBoxLayout( viewWidget(), 2 );
// The list view will be created when the config is read.
mListView = 0;
}
KAddressBookTableView::~KAddressBookTableView()
{
}
void KAddressBookTableView::setFocusAV()
{
if ( mListView )
mListView->setFocus();
}
void KAddressBookTableView::scrollUP()
{
QKeyEvent * ev = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Up, 0,0 );
QApplication::postEvent( mListView, ev );
+ ev = new QKeyEvent ( QEvent::KeyRelease, Qt::Key_Up, 0,0 );
+ QApplication::postEvent( mListView, ev );
}
void KAddressBookTableView::scrollDOWN()
{
QKeyEvent * ev = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Down, 0,0 );
QApplication::postEvent( mListView, ev );
+ ev = new QKeyEvent ( QEvent::KeyRelease, Qt::Key_Down, 0,0 );
+ QApplication::postEvent( mListView, ev );
}
void KAddressBookTableView::reconstructListView()
{
if (mListView)
{
disconnect(mListView, SIGNAL(selectionChanged()),
this, SLOT(addresseeSelected()));
disconnect(mListView, SIGNAL(executed(QListViewItem*)),
this, SLOT(addresseeExecuted(QListViewItem*)));
disconnect(mListView, SIGNAL(doubleClicked(QListViewItem*)),
this, SLOT(addresseeExecuted(QListViewItem*)));
disconnect(mListView, SIGNAL(startAddresseeDrag()), this,
SIGNAL(startDrag()));
disconnect(mListView, SIGNAL(returnPressed(QListViewItem*)),
this, SLOT(addresseeExecuted(QListViewItem*)));
disconnect(mListView, SIGNAL(addresseeDropped(QDropEvent*)), this,
SIGNAL(dropped(QDropEvent*)));
delete mListView;
}
mListView = new ContactListView( this, addressBook(), viewWidget() );
connect(this, SIGNAL(printView()),
mListView , SLOT(printMe()));
//US set singleClick manually, because it is no global configparameter in embedded space
mListView->setSingleClick(KABPrefs::instance()->mHonorSingleClick);
// Add the columns
KABC::Field::List fieldList = fields();
KABC::Field::List::ConstIterator it;
int c = 0;
for( it = fieldList.begin(); it != fieldList.end(); ++it ) {
mListView->addColumn( (*it)->label() );
mListView->setColumnWidthMode(c++, QListView::Manual);
//US
// qDebug("KAddressBookTableView::reconstructListView: field %s", (*it)->label().latin1());
}
connect(mListView, SIGNAL(selectionChanged()),
this, SLOT(addresseeSelected()));
connect(mListView, SIGNAL(startAddresseeDrag()), this,
SIGNAL(startDrag()));
connect(mListView, SIGNAL(addresseeDropped(QDropEvent*)), this,
SIGNAL(dropped(QDropEvent*)));
if (KABPrefs::instance()->mHonorSingleClick) {
// qDebug("KAddressBookTableView::reconstructListView single");
connect(mListView, SIGNAL(executed(QListViewItem*)),
this, SLOT(addresseeExecuted(QListViewItem*)));
} else {
// qDebug("KAddressBookTableView::reconstructListView double");
connect(mListView, SIGNAL(doubleClicked(QListViewItem*)),
this, SLOT(addresseeExecuted(QListViewItem*)));
}
connect(mListView, SIGNAL(returnPressed(QListViewItem*)),
this, SLOT(addresseeExecuted(QListViewItem*)));
connect(mListView, SIGNAL(signalDelete()),
this, SLOT(addresseeDeleted()));
//US performceimprovement. Refresh is done from the outside
//US refresh();
mListView->setSorting( 0, true );
mainLayout->addWidget( mListView );
mainLayout->activate();
mListView->show();
}
void KAddressBookTableView::doSearch( const QString& s, KABC::Field *field )
{
mListView->clear();
if ( s.isEmpty() || s == "*" ) {
refresh();
return;
}
QRegExp re = getRegExp( s );
if (!re.isValid())
return;
KABC::Addressee::List addresseeList = addressees();
KABC::Addressee::List::Iterator it;
if ( field ) {
for (it = addresseeList.begin(); it != addresseeList.end(); ++it ) {
if ( (*it).uid().left(2) == "la" && (*it).uid().left(19) == QString("last-syncAddressee-") )
continue;
#if QT_VERSION >= 0x030000
if (re.search(field->value( *it ).lower()) == 0)
#else
if (re.match(field->value( *it ).lower()) != -1)
#endif
ContactListViewItem *item = new ContactListViewItem(*it, mListView, addressBook(), fields());
}
} else {
KABC::Field::List fieldList = allFields();
KABC::Field::List::ConstIterator fieldIt;
for (it = addresseeList.begin(); it != addresseeList.end(); ++it ) {
if ( (*it).uid().left(2) == "la" && (*it).uid().left(19) == QString("last-syncAddressee-") )
continue;
for ( fieldIt = fieldList.begin(); fieldIt != fieldList.end(); ++fieldIt ) {
#if QT_VERSION >= 0x030000
if (re.search((*fieldIt)->value( *it ).lower()) != -1)
#else
if (re.match((*fieldIt)->value( *it ).lower()) != -1)
#endif
{
//qDebug("match %s %s %s", pattern.latin1(), (*fieldIt)->value( *it ).latin1(), (*fieldIt)->label().latin1() );
ContactListViewItem *item = new ContactListViewItem(*it, mListView, addressBook(), fields());
break;
}
}
}
}
// Sometimes the background pixmap gets messed up when we add lots
// of items.
mListView->repaint();
if ( mListView->firstChild() ) {
mListView->setCurrentItem ( mListView->firstChild() );
mListView->setSelected ( mListView->firstChild(), true );
}
else
emit selected(QString::null);
}
void KAddressBookTableView::writeConfig(KConfig *config)
{
KAddressBookView::writeConfig(config);
mListView->saveLayout(config, config->group());
}
void KAddressBookTableView::readConfig(KConfig *config)
{
KAddressBookView::readConfig( config );
// The config could have changed the fields, so we need to reconstruct
// the listview.
reconstructListView();
// costum colors?
if ( config->readBoolEntry( "EnableCustomColors", false ) )
{
QPalette p( mListView->palette() );
QColor c = p.color(QPalette::Normal, QColorGroup::Base );
p.setColor( QPalette::Normal, QColorGroup::Base, config->readColorEntry( "BackgroundColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::Text );
p.setColor( QPalette::Normal, QColorGroup::Text, config->readColorEntry( "TextColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::Button );
p.setColor( QPalette::Normal, QColorGroup::Button, config->readColorEntry( "HeaderColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::ButtonText );
p.setColor( QPalette::Normal, QColorGroup::ButtonText, config->readColorEntry( "HeaderTextColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::Highlight );
p.setColor( QPalette::Normal, QColorGroup::Highlight, config->readColorEntry( "HighlightColor", &c ) );
c = p.color(QPalette::Normal, QColorGroup::HighlightedText );
p.setColor( QPalette::Normal, QColorGroup::HighlightedText, config->readColorEntry( "HighlightedTextColor", &c ) );
#ifndef KAB_EMBEDDED
c = KGlobalSettings::alternateBackgroundColor();
#else //KAB_EMBEDDED
c = QColor(240, 240, 240);
#endif //KAB_EMBEDDED
c = config->readColorEntry ("AlternatingBackgroundColor", &c);
mListView->setAlternateColor(c);
//US mListView->viewport()->setPalette( p );
mListView->setPalette( p );
}
else
{
// needed if turned off during a session.
//US mListView->viewport()->setPalette( mListView->palette() );
mListView->setPalette( mListView->palette() );
}
//custom fonts?
QFont f( font() );
if ( config->readBoolEntry( "EnableCustomFonts", false ) )
{
mListView->setFont( config->readFontEntry( "TextFont", &f) );
f.setBold( true );
//US mListView->setHeaderFont( config->readFontEntry( "HeaderFont", &f ) );
mListView->header()->setFont( config->readFontEntry( "HeaderFont", &f ) );
}
else
{
mListView->setFont( f );
f.setBold( true );
//US mListView->setHeaderFont( f );
mListView->header()->setFont( f );
}
// Set the list view options
mListView->setAlternateBackgroundEnabled(config->readBoolEntry("ABackground",
true));
mListView->setSingleLineEnabled(config->readBoolEntry("SingleLine", false));
mListView->setToolTipsEnabled(config->readBoolEntry("ToolTips", true));
if (config->readBoolEntry("Background", false))
mListView->setBackgroundPixmap(config->readEntry("BackgroundName"));
// Restore the layout of the listview
mListView->restoreLayout(config, config->group());
}
void KAddressBookTableView::refresh(QString uid)
{
// For now just repopulate. In reality this method should
// check the value of uid, and if valid iterate through
// the listview to find the entry, then tell it to refresh.
if (uid.isNull()) {
// Clear the list view
QString currentUID, nextUID;
#ifndef KAB_EMBEDDED
ContactListViewItem *currentItem = dynamic_cast<ContactListViewItem*>( mListView->currentItem() );
#else //KAB_EMBEDDED
ContactListViewItem *currentItem = (ContactListViewItem*)( mListView->currentItem() );
#endif //KAB_EMBEDDED
if ( currentItem ) {
#ifndef KAB_EMBEDDED
ContactListViewItem *nextItem = dynamic_cast<ContactListViewItem*>( currentItem->itemBelow() );
#else //KAB_EMBEDDED
ContactListViewItem *nextItem = (ContactListViewItem*)( currentItem->itemBelow() );
#endif //KAB_EMBEDDED
if ( nextItem )
nextUID = nextItem->addressee().uid();
currentUID = currentItem->addressee().uid();
}
mListView->clear();
currentItem = 0;
KABC::Addressee::List addresseeList = addressees();
KABC::Addressee::List::Iterator it;
for (it = addresseeList.begin(); it != addresseeList.end(); ++it ) {
if ( (*it).uid().left(2) == "la" && (*it).uid().left(19) == QString("last-syncAddressee-") )
continue;
ContactListViewItem *item = new ContactListViewItem(*it, mListView, addressBook(), fields());
if ( (*it).uid() == currentUID )
currentItem = item;
else if ( (*it).uid() == nextUID && !currentItem )
currentItem = item;
}
// Sometimes the background pixmap gets messed up when we add lots
// of items.
mListView->repaint();
if ( currentItem ) {
mListView->setCurrentItem( currentItem );
mListView->ensureItemVisible( currentItem );
}
} else {
// Only need to update on entry. Iterate through and try to find it
ContactListViewItem *ceItem;
QListViewItemIterator it( mListView );
while ( it.current() ) {
#ifndef KAB_EMBEDDED
ceItem = dynamic_cast<ContactListViewItem*>( it.current() );
#else //KAB_EMBEDDED
ceItem = (ContactListViewItem*)( it.current() );
#endif //KAB_EMBEDDED
if ( ceItem && ceItem->addressee().uid() == uid ) {
ceItem->refresh();
return;
}
++it;
}
refresh( QString::null );
}
}
QStringList KAddressBookTableView::selectedUids()
{
QStringList uidList;
QListViewItem *item;
ContactListViewItem *ceItem;
for(item = mListView->firstChild(); item; item = item->itemBelow())
{
if (mListView->isSelected( item ))
{
#ifndef KAB_EMBEDDED
ceItem = dynamic_cast<ContactListViewItem*>(item);
#else //KAB_EMBEDDED
ceItem = (ContactListViewItem*)(item);
#endif //KAB_EMBEDDED
if (ceItem != 0L)
uidList << ceItem->addressee().uid();
}
}
if ( uidList.count() == 0 )
if ( mListView->currentItem() ) {
ceItem = (ContactListViewItem*)(mListView->currentItem()) ;
uidList << ceItem->addressee().uid();
}
return uidList;
}
void KAddressBookTableView::setSelected(QString uid, bool selected)
{
QListViewItem *item;
ContactListViewItem *ceItem;
if (uid.isNull())
{
mListView->selectAll(selected);
}
else
{
for(item = mListView->firstChild(); item; item = item->itemBelow())
{
#ifndef KAB_EMBEDDED
ceItem = dynamic_cast<ContactListViewItem*>(item);
#else //KAB_EMBEDDED
ceItem = (ContactListViewItem*)(item);
#endif //KAB_EMBEDDED
if ((ceItem != 0L) && (ceItem->addressee().uid() == uid))
{
mListView->setSelected(item, selected);
if (selected)
mListView->ensureItemVisible(item);
}
}
}
}
void KAddressBookTableView::addresseeSelected()
{
// We need to try to find the first selected item. This might not be the
// last selected item, but when QListView is in multiselection mode,
// there is no way to figure out which one was
// selected last.
QListViewItem *item;
bool found =false;
for (item = mListView->firstChild(); item && !found;
item = item->nextSibling())
{
if (item->isSelected())
{
found = true;
#ifndef KAB_EMBEDDED
ContactListViewItem *ceItem
= dynamic_cast<ContactListViewItem*>(item);
#else //KAB_EMBEDDED
ContactListViewItem *ceItem
= (ContactListViewItem*)(item);
#endif //KAB_EMBEDDED
if ( ceItem ) emit selected(ceItem->addressee().uid());
}
}
if (!found)
emit selected(QString::null);
}
void KAddressBookTableView::addresseeExecuted(QListViewItem *item)
{
if (item)
{
#ifndef KAB_EMBEDDED
ContactListViewItem *ceItem
= dynamic_cast<ContactListViewItem*>(item);
#else //KAB_EMBEDDED
ContactListViewItem *ceItem
= (ContactListViewItem*)(item);
#endif //KAB_EMBEDDED
if (ceItem)
{
emit executed(ceItem->addressee().uid());
}
}
else
{
emit executed(QString::null);
}
}
void KAddressBookTableView::addresseeDeleted()
{
emit deleteRequest();
}
#ifndef KAB_EMBEDDED
#include "kaddressbooktableview.moc"
#endif //KAB_EMBEDDED
diff --git a/korganizer/komonthview.cpp b/korganizer/komonthview.cpp
index ca35a86..b9ce4f4 100644
--- a/korganizer/komonthview.cpp
+++ b/korganizer/komonthview.cpp
@@ -491,1396 +491,1413 @@ QPalette MonthViewCell::getPalette ()
{
if ( !KOPrefs::instance()->mMonthViewUsesDayColors )
return mStandardPalette;
if ( mHoliday) {
return mHolidayPalette ;
} else {
if ( mPrimary ) {
return mPrimaryPalette ;
}
}
return mNonPrimaryPalette;
}
bool MonthViewCell::isPrimary() const
{
return mPrimary;
}
void MonthViewCell::setHoliday( bool holiday )
{
mHoliday = holiday;
//setMyPalette();
}
void MonthViewCell::setHoliday( const QString &holiday )
{
mHolidayString = holiday;
if ( !holiday.isEmpty() ) {
setHoliday( true );
}
}
void MonthViewCell::startUpdateCell()
{
setFocusPolicy(NoFocus);
if ( !mMonthView->isUpdatePossible() )
return;
MonthViewItem *mitem = (MonthViewItem*) firstItem ();
while ( mitem ) {
mitem->setBlockRepaint( true );
mitem = (MonthViewItem *)mitem->next();
}
if ( mAvailItemList.count() > 20 ) {
mAvailItemList.setAutoDelete( true );
mAvailItemList.clear();
mAvailItemList.setAutoDelete( false );
}
/*
if ( !isVisible() ){
return;
}
*/
// qDebug("MonthViewCell::updateCell() ");
setPrimary( mDate.month()%2 );
setHoliday( KOGlobals::self()->calendarSystem()->dayOfWeek(mDate) == KOGlobals::self()->calendarSystem()->weekDayOfPray() || ( mDate.dayOfWeek() == 6 ) && KOPrefs::instance()-> mExcludeSaturdays);
if ( mDate == QDate::currentDate() ) {
setLineWidth( 3 );
} else {
setLineWidth( 1 );
}
mCurrentAvailItem = (MonthViewItem*) firstItem ();
//clear();
#ifdef DESKTOP_VERSION
QToolTip::remove(this);
#endif
mToolTip.clear();
//qApp->processEvents();
#if 0
if ( !mHolidayString.isEmpty() ) {
MonthViewItem *item = new MonthViewItem( 0, mDate, mHolidayString );
item->setPalette( mHolidayPalette );
insertItem( item );
mToolTip.append ( mHolidayString );
}
#endif
}
void MonthViewCell::insertEvent(Event *event)
{
QString mToolTipText;
bool insertNewItem = false;
setFocusPolicy(WheelFocus);
if ( !(event->doesRecur() == Recurrence::rNone) ) {
if ( !KOPrefs::instance()->mMonthDailyRecur && event->doesRecur() == Recurrence::rDaily )
return;
else
if ( !KOPrefs::instance()->mMonthWeeklyRecur && event->doesRecur() == Recurrence::rWeekly )
return;
}
if ( event->isHoliday()) {
setHoliday( true );
if ( mDate.dayOfWeek() == 7 )
setLineWidth( 3 );
}
QString text;
int multiday = 0;// 1 = start, 2 = midddle, 3 = end day
if (event->isMultiDay()) {
QString prefix = "<->";multiday = 2;
QString time;
if ( event->doesRecur() ) {
if ( event->recursOn( mDate) ) {
prefix ="->" ;multiday = 1;
}
else {
int days = event->dtStart().date().daysTo ( event->dtEnd().date() );
if ( event->recursOn( mDate.addDays( -days)) ) {
prefix ="<-" ;multiday = 3;
}
}
} else {
if (mDate == event->dtStart().date()) {
prefix ="->" ;multiday = 1;
} else if (mDate == event->dtEnd().date()) {
prefix ="<-" ;multiday = 3;
}
}
if ( !event->doesFloat() ) {
if ( mDate == event->dtStart().date () )
time = KGlobal::locale()->formatTime(event->dtStart().time())+" ";
else if ( mDate == event->dtEnd().date () )
time = KGlobal::locale()->formatTime(event->dtEnd().time())+" ";
}
text = time + event->summary();
mToolTipText += prefix + text;
} else {
if (event->doesFloat()) {
text = event->summary();
mToolTipText += text;
}
else {
text = KGlobal::locale()->formatTime(event->dtStart().time());
text += " " + event->summary();
mToolTipText += KGlobal::locale()->formatTime(event->dtStart().time()) +"-"+KGlobal::locale()->formatTime(event->dtEnd().time())+" " + event->summary();
}
}
MonthViewItem *item ;
if ( mCurrentAvailItem ) {
item = mCurrentAvailItem;
mCurrentAvailItem = (MonthViewItem*) item->next();
item->recycle( event, mDate, text );
} else {
if ( mAvailItemList.count() ) {
item = mAvailItemList.first();
mAvailItemList.remove( item );
item->recycle( event, mDate, text );
insertNewItem = true;
} else {
insertNewItem = true;
item = new MonthViewItem( event, mDate, text );
}
}
QPalette pal;
if (KOPrefs::instance()->mMonthViewUsesCategoryColor) {
QStringList categories = event->categories();
QString cat = categories.first();
if ( KOPrefs::instance()->mMonthViewUsesForegroundColor ) {
pal = getPalette();
if (cat.isEmpty()) {
pal.setColor(QColorGroup::Foreground,KOPrefs::instance()->mEventColor);
} else {
pal.setColor(QColorGroup::Foreground, *(KOPrefs::instance()->categoryColor(cat)));
}
} else {
if (cat.isEmpty()) {
pal = QPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor);
} else {
pal = QPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat)));
}
}
} else {
pal = mStandardPalette ;
}
item->setPalette( pal );
item->setRecur( event->recurrence()->doesRecur() );
item->setAlarm( event->isAlarmEnabled() && multiday < 2 );
item->setMoreInfo( event->description().length() > 0 );
#ifdef DESKTOP_VERSION
Attendee *me = event->attendeeByMails(KOPrefs::instance()->mAdditionalMails,
KOPrefs::instance()->email());
if ( me != 0 ) {
if ( me->status() == Attendee::NeedsAction && me->RSVP())
item->setReply(true && multiday < 2);
else
item->setReply(false);
} else
item->setReply(false);
#endif
item->setMultiDay( multiday );
if ( insertNewItem)
insertItem( item );
mToolTip.append( mToolTipText );
}
void MonthViewCell::insertTodo(Todo *todo)
{
bool insertNewItem = false;
setFocusPolicy(WheelFocus);
QString text;
if (todo->hasDueDate()) {
if (!todo->doesFloat()) {
text += KGlobal::locale()->formatTime(todo->dtDue().time());
text += " ";
}
}
text += todo->summary();
MonthViewItem *item ;
if ( mCurrentAvailItem ) {
item = mCurrentAvailItem;
mCurrentAvailItem = (MonthViewItem*) item->next();
item->recycle( todo, mDate, text );
} else {
if ( mAvailItemList.count() ) {
item = mAvailItemList.first();
mAvailItemList.remove( item );
item->recycle( todo, mDate, text );
insertNewItem = true;
} else {
insertNewItem = true;
item = new MonthViewItem( todo, mDate, text );
}
}
//MonthViewItem *item = new MonthViewItem( todo, mDate, text );
//item->setPalette( mStandardPalette );
QPalette pal;
if (KOPrefs::instance()->mMonthViewUsesCategoryColor) {
QStringList categories = todo->categories();
QString cat = categories.first();
if ( KOPrefs::instance()->mMonthViewUsesForegroundColor ) {
pal = getPalette();
if (cat.isEmpty()) {
pal.setColor(QColorGroup::Foreground,KOPrefs::instance()->mEventColor);
} else {
pal.setColor(QColorGroup::Foreground, *(KOPrefs::instance()->categoryColor(cat)));
}
} else {
if (cat.isEmpty()) {
pal = QPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor);
} else {
pal = QPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat)));
}
}
} else {
pal = mStandardPalette ;
}
item->setPalette( pal );
item->setRecur( todo->recurrence()->doesRecur() );
item->setAlarm( todo->isAlarmEnabled() );
item->setMoreInfo( todo->description().length() > 0 );
if ( insertNewItem)
insertItem( item );
mToolTip.append( text );
}
void MonthViewCell::repaintfinishUpdateCell()
{
MonthViewItem *mitem = (MonthViewItem*) firstItem ();
while ( mitem ) {
mitem->setBlockRepaint( false );
updateItem ( mitem );
mitem = (MonthViewItem *)mitem->next();
}
}
void MonthViewCell::finishUpdateCell()
{
while ( mCurrentAvailItem ) {
MonthViewItem *item = mCurrentAvailItem;
mCurrentAvailItem = (MonthViewItem *)item->next();
mAvailItemList.append( item );
takeItem ( item );
}
#ifdef DESKTOP_VERSION
if (mToolTip.count() > 0 ) {
mToolTip.sort();
QToolTip::add(this,mToolTip.join("\n"),toolTipGroup(),"");
}
#endif
sort();
//setMyPalette();
setMyPalette();
resizeEvent( 0 );
}
void MonthViewCell::updateCell()
{
//qDebug("MonthViewCell::updateCell() ");
if ( !mMonthView->isUpdatePossible() )
return;
startUpdateCell();
//mLabel->setMaximumWidth( width() - mItemList->lineWidth()*2);
QPtrList<Event> events = mMonthView->calendar()->events( mDate, true );
Event *event;
for( event = events.first(); event; event = events.next() ) { // for event
insertEvent(event);
}
// insert due todos
QPtrList<Todo> todos = mMonthView->calendar()->todos( mDate );
Todo *todo;
for(todo = todos.first(); todo; todo = todos.next()) {
insertTodo( todo );
}
finishUpdateCell();
// if ( isVisible())
//qApp->processEvents();
}
void MonthViewCell::updateConfig( bool bigFont ) // = false
{
if ( bigFont ) {
QFont fo = KOPrefs::instance()->mMonthViewFont;
int ps = fo.pointSize() + 2;
if ( ps < 18 )
ps += 2;
fo.setPointSize( ps );
setFont( fo );
} else
setFont( KOPrefs::instance()->mMonthViewFont );
QFontMetrics fm( font() );
mLabelSize = fm.size( 0, "30" ) + QSize( 4, 2 );
mLabelBigSize = fm.size( 0, "Mag 30" ) + QSize( 2, 2 );
mHolidayPalette = mStandardPalette;
mPrimaryPalette = mStandardPalette;
mNonPrimaryPalette = mStandardPalette;
if ( KOPrefs::instance()->mMonthViewUsesDayColors ) {
mHolidayPalette.setColor(QColorGroup::Base, KOPrefs::instance()->mMonthViewHolidayColor );
mHolidayPalette.setColor(QColorGroup::Background, KOPrefs::instance()->mMonthViewHolidayColor );
mHolidayPalette.setColor(QColorGroup::Foreground, KOPrefs::instance()->mMonthViewHolidayColor.dark());
mPrimaryPalette.setColor(QColorGroup::Foreground,KOPrefs::instance()->mMonthViewOddColor.dark());
mPrimaryPalette.setColor(QColorGroup::Base,KOPrefs::instance()->mMonthViewOddColor);
mPrimaryPalette.setColor(QColorGroup::Background,KOPrefs::instance()->mMonthViewOddColor);
mNonPrimaryPalette.setColor(QColorGroup::Foreground,KOPrefs::instance()->mMonthViewEvenColor.dark());
mNonPrimaryPalette.setColor(QColorGroup::Base,KOPrefs::instance()->mMonthViewEvenColor);
mNonPrimaryPalette.setColor(QColorGroup::Background,KOPrefs::instance()->mMonthViewEvenColor);
}
//updateCell();
}
void MonthViewCell::enableScrollBars( bool enabled )
{
if ( enabled ) {
QListBoxItem *fi = firstItem ();
if (fi ) {
int ihei = fi->height( this );
int hei = numRows () * ihei;
if ( hei < height() - horizontalScrollBar()->height () ) {
setVScrollBarMode(QScrollView::AlwaysOff);
}
else
setVScrollBarMode(QScrollView::Auto);
if ( ihei *3 > height() )
setHScrollBarMode(QScrollView::AlwaysOff);
else
setHScrollBarMode(QScrollView::Auto);
} else {
setVScrollBarMode(QScrollView::Auto);
setHScrollBarMode(QScrollView::Auto);
}
} else {
setVScrollBarMode(QScrollView::AlwaysOff);
setHScrollBarMode(QScrollView::AlwaysOff);
}
}
Incidence *MonthViewCell::selectedIncidence()
{
int index = currentItem();
if ( index < 0 ) return 0;
MonthViewItem *mitem =
static_cast<MonthViewItem *>( item( index ) );
if ( !mitem ) return 0;
return mitem->incidence();
}
QDate MonthViewCell::selectedIncidenceDate()
{
QDate qd;
int index = currentItem();
if ( index < 0 ) return qd;
MonthViewItem *mitem =
static_cast<MonthViewItem *>( item( index ) );
if ( !mitem ) return qd;
return mitem->incidenceDate();
}
void MonthViewCell::deselect()
{
clearSelection();
enableScrollBars( false );
// updateCell();
}
void MonthViewCell::select()
{
;// updateCell();
}
void MonthViewCell::resizeEvent ( QResizeEvent * e )
{
if ( !mMonthView->isUpdatePossible() )
return;
//qDebug("++++++++++++++MonthViewCell::resizeEvent %d %d ", width(), height());
deselect();
mLabel->setMaximumHeight( height() - lineWidth()*2 );
QString text;
mLabel->setText( text );
bool smallDisplay = QApplication::desktop()->width() < 320 && KOPrefs::instance()->mMonthViewSatSunTog;
if ( KOPrefs::instance()->mMonthViewWeek || KOGlobals::self()->calendarSystem()->day( mDate ) == 1 || (mDate.dayOfWeek() == 7 && !smallDisplay ) || KOPrefs::instance()->mMonthShowShort) {
text = KOGlobals::self()->calendarSystem()->monthName( mDate, true ) + " ";
mLabel->resize( mLabelBigSize );
text += QString::number( KOGlobals::self()->calendarSystem()->day(mDate) );
} else {
mLabel->resize( mLabelSize );
text += QString::number( KOGlobals::self()->calendarSystem()->day(mDate) );
}
mLabel->setText( text );
int size = height() - mLabel->height() - lineWidth()-1;
//qDebug("LW %d ", lineWidth());
if ( size > 0 )
verticalScrollBar()->setMaximumHeight( size );
size = width() - mLabel->width() -lineWidth()-1;
if ( size > 0 )
horizontalScrollBar()->setMaximumWidth( size );
mLabel->move( width()-lineWidth() - mLabel->width(), height()-lineWidth() - mLabel->height() );
//mLabel->setMaximumWidth( width() - mItemList->lineWidth()*2);
// mItemList->resize ( width(), height () );
if ( e )
KNoScrollListBox::resizeEvent ( e );
}
void MonthViewCell::defaultAction( QListBoxItem *item )
{
if ( !item ) return;
MonthViewItem *eventItem = static_cast<MonthViewItem *>( item );
Incidence *incidence = eventItem->incidence();
if ( incidence ) mMonthView->defaultAction( incidence );
}
void MonthViewCell::showDay()
{
emit showDaySignal( date() );
}
void MonthViewCell::newEvent()
{
QDateTime dt( date(), QTime( KOPrefs::instance()->mStartTime, 0 ) );
emit newEventSignal( dt );
}
void MonthViewCell::cellClicked( QListBoxItem *item )
{
static QListBoxItem * lastClicked = 0;
if ( item == 0 ) {
QDateTime dt( date(), QTime( KOPrefs::instance()->mStartTime, 0 ) );
emit newEventSignal( dt );
return;
}
/*
if ( lastClicked )
if ( ! item ) {
if ( lastClicked->listBox() != item->listBox() )
lastClicked->listBox()->clearSelection();
}
*/
mMonthView->setSelectedCell( this );
if( KOPrefs::instance()->mEnableMonthScroll || KOPrefs::instance()->mMonthViewWeek ) enableScrollBars( true );
select();
}
void MonthViewCell::contextMenu( QListBoxItem *item )
{
if ( !item ) return;
MonthViewItem *eventItem = static_cast<MonthViewItem *>( item );
Incidence *incidence = eventItem->incidence();
if ( incidence ) mMonthView->showContextMenu( incidence );
}
void MonthViewCell::selection( QListBoxItem *item )
{
if ( !item ) return;
mMonthView->setSelectedCell( this );
}
// *******************************************************************************
// *******************************************************************************
// *******************************************************************************
KOMonthView::KOMonthView(Calendar *calendar, QWidget *parent, const char *name)
: KOEventView( calendar, parent, name ),
mDaysPerWeek( 7 ), mNumWeeks( 6 ), mNumCells( mDaysPerWeek * mNumWeeks ),
mWidthLongDayLabel( 0 ), mSelectedCell( 0 )
{
+ mFlagKeyPressed = false;
mShortDayLabelsM = false;
mShortDayLabelsW = false;
skipResize = false;
clPending = true;
mNavigatorBar = new NavigatorBar( QDate::currentDate(), this, "useBigPixmaps" );
mWidStack = new QWidgetStack( this );
QVBoxLayout* hb = new QVBoxLayout( this );
mMonthView = new QWidget( mWidStack );
mWeekView = new QWidget( mWidStack );
#if QT_VERSION >= 0x030000
mWidStack->addWidget(mMonthView );
mWidStack->addWidget(mWeekView );
#else
mWidStack->addWidget( mMonthView, 1 );
mWidStack->addWidget( mWeekView , 1 );
#endif
hb->addWidget( mNavigatorBar );
hb->addWidget( mWidStack );
mShowWeekView = KOPrefs::instance()->mMonthViewWeek;
updatePossible = false;
//updatePossible = true;
mCells.setAutoDelete( true );
mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ;
mDayLabels.resize( mDaysPerWeek );
mDayLabelsW.resize( mDaysPerWeek );
QFont bfont = font();
if ( QApplication::desktop()->width() < 650 ) {
bfont.setPointSize( bfont.pointSize() - 2 );
}
bfont.setBold( true );
int i;
for( i = 0; i < mDaysPerWeek; i++ ) {
QLabel *label = new QLabel( mMonthView );
label->setFont(bfont);
label->setFrameStyle(QFrame::Panel|QFrame::Raised);
label->setLineWidth(1);
label->setAlignment(AlignCenter);
mDayLabels.insert( i, label );
label = new QLabel( mWeekView );
label->setFont(bfont);
label->setFrameStyle(QFrame::Panel|QFrame::Raised);
label->setLineWidth(1);
label->setAlignment(AlignCenter);
mDayLabelsW.insert( i, label );
}
bfont.setBold( false );
mWeekLabels.resize( mNumWeeks+1 );
mWeekLabelsW.resize( 2 );
for( i = 0; i < mNumWeeks+1; i++ ) {
KOWeekButton *label = new KOWeekButton( mMonthView );
label->setFocusPolicy(NoFocus);
label->setFont(bfont);
connect( label, SIGNAL( selectWeekNum ( int )),this, SLOT( selectInternalWeekNum ( int )) );
label->setFlat(true);
QWhatsThis::add(label,i18n("Click on the week number to\nshow week zoomed"));
//label->setFrameStyle(QFrame::Panel|QFrame::Raised);
//label->setLineWidth(1);
//label->setAlignment(AlignCenter);
mWeekLabels.insert( i, label );
}
mWeekLabels[mNumWeeks]->setText( i18n("W"));
mWeekLabels[0]->setFocusPolicy(WheelFocus);
QWhatsThis::add(mWeekLabels[mNumWeeks],i18n("Click on this to\nselect week number"));
for( i = 0; i < 1+1; i++ ) {
KOWeekButton *label = new KOWeekButton( mWeekView );
label->setFocusPolicy(NoFocus);
label->setFont(bfont);
connect( label, SIGNAL( selectWeekNum ( int )),this, SLOT( selectInternalWeekNum ( int )) );
label->setFlat(true);
QWhatsThis::add(label,i18n("Click on the week number to\nshow week zoomed"));
//label->setFrameStyle(QFrame::Panel|QFrame::Raised);
//label->setLineWidth(1);
//label->setAlignment(AlignCenter);
mWeekLabelsW.insert( i, label );
}
mWeekLabelsW[1]->setText( i18n("W"));
mWeekLabelsW[0]->setFocusPolicy(WheelFocus);
int row, col;
mCells.resize( mNumCells );
for( row = 0; row < mNumWeeks; ++row ) {
for( col = 0; col < mDaysPerWeek; ++col ) {
MonthViewCell *cell = new MonthViewCell( this, mMonthView );
mCells.insert( row * mDaysPerWeek + col, cell );
connect( cell, SIGNAL( defaultAction( Incidence * ) ),
SLOT( defaultAction( Incidence * ) ) );
connect( cell, SIGNAL( newEventSignal( QDateTime ) ),
SIGNAL( newEventSignal( QDateTime ) ) );
connect( cell, SIGNAL( showDaySignal( QDate ) ),
SIGNAL( showDaySignal( QDate ) ) );
}
}
mCellsW.resize( mDaysPerWeek );
for( col = 0; col < mDaysPerWeek; ++col ) {
MonthViewCell *cell = new MonthViewCell( this, mWeekView );
mCellsW.insert( col, cell );
connect( cell, SIGNAL( defaultAction( Incidence * ) ),
SLOT( defaultAction( Incidence * ) ) );
connect( cell, SIGNAL( newEventSignal( QDateTime ) ),
SIGNAL( newEventSignal( QDateTime ) ) );
connect( cell, SIGNAL( showDaySignal( QDate ) ),
SIGNAL( showDaySignal( QDate ) ) );
cell->updateConfig(KOPrefs::instance()->mMonthViewUsesBigFont );
}
//connect( mWeekLabels[mNumWeeks], SIGNAL( clicked() ), SLOT( switchView() ) );
mContextMenu = eventPopup();
// updateConfig(); //useless here...
// ... but we need mWidthLongDayLabel computed
QFontMetrics fontmetric(mDayLabels[0]->font());
mWidthLongDayLabel = 0;
for (int i = 0; i < 7; i++) {
int width = fontmetric.width(KOGlobals::self()->calendarSystem()->weekDayName(i+1));
if ( width > mWidthLongDayLabel ) mWidthLongDayLabel = width;
}
//mWeekLabels[mNumWeeks]->setText( i18n("W"));
#if 0
if ( mShowWeekView )
mWidStack->raiseWidget( mWeekView );
else
mWidStack->raiseWidget( mMonthView );
#endif
emit incidenceSelected( 0 );
mComputeLayoutTimer = new QTimer( this );
connect (mComputeLayoutTimer ,SIGNAL(timeout()), this, SLOT ( slotComputeLayout()));
#ifndef DESKTOP_VERSION
resize( QApplication::desktop()->size() );
#else
resize(640, 480 );
updatePossible = true;
#endif
computeLayout();
if ( mShowWeekView )
mWidStack->raiseWidget( mWeekView );
else
mWidStack->raiseWidget( mMonthView );
}
KOMonthView::~KOMonthView()
{
delete mContextMenu;
}
void KOMonthView::selectInternalWeekNum ( int n )
{
switchView();
if ( !KOPrefs::instance()->mMonthViewWeek )
emit selectMonth ();
else
emit selectWeekNum ( n );
}
int KOMonthView::currentWeek()
{
if ( mShowWeekView )
return mWeekLabelsW[0]->getWeekNum();
return mWeekLabels[0]->getWeekNum();
}
void KOMonthView::switchView()
{
if ( selectedCell( ) )
selectedCell()->deselect();
mShowWeekView = !mShowWeekView;
KOPrefs::instance()->mMonthViewWeek = mShowWeekView;
if ( clPending ) {
computeLayout();
updateConfig();
}
if ( mShowWeekView )
mWidStack->raiseWidget( mWeekView );
else
mWidStack->raiseWidget( mMonthView );
clPending = false;
}
int KOMonthView::maxDatesHint()
{
return mNumCells;
}
int KOMonthView::currentDateCount()
{
return mNumCells;
}
QPtrList<Incidence> KOMonthView::selectedIncidences()
{
QPtrList<Incidence> selected;
if ( mSelectedCell ) {
Incidence *incidence = mSelectedCell->selectedIncidence();
if ( incidence ) selected.append( incidence );
}
return selected;
}
DateList KOMonthView::selectedDates()
{
DateList selected;
if ( mSelectedCell ) {
QDate qd = mSelectedCell->selectedIncidenceDate();
if ( qd.isValid() ) selected.append( qd );
}
return selected;
}
void KOMonthView::printPreview(CalPrinter *calPrinter, const QDate &fd,
const QDate &td)
{
#ifndef KORG_NOPRINTER
calPrinter->preview(CalPrinter::Month, fd, td);
#endif
}
void KOMonthView::updateConfig()
{
int mWeekStartsMonday = KGlobal::locale()->weekStartsMonday();
if ( mShowWeekView || KOPrefs::instance()->mMonthViewSatSunTog ) {
mWeekStartsMonday = true;
}
QFontMetrics fontmetric(mDayLabels[0]->font());
mWidthLongDayLabel = 0;
for (int i = 0; i < 7; i++) {
int width = fontmetric.width(KOGlobals::self()->calendarSystem()->weekDayName(i+1));
if ( width > mWidthLongDayLabel ) mWidthLongDayLabel = width;
}
bool temp = mShowSatSunComp ;
mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ;
if ( ! mShowWeekView ) {
if ( temp != KOPrefs::instance()->mMonthViewSatSunTog )
computeLayout();
}
updateDayLabels();
//qDebug("KOMonthView::updateConfig() %d %d %d ",height(), mDayLabels[0]->sizeHint().height() ,mNumWeeks);
//int cellHeight = (height() - mDayLabels[0]->sizeHint().height()) /mNumWeeks;
//resizeEvent( 0 );
for (uint i = 0; i < mCells.count(); ++i) {
mCells[i]->updateConfig();
}
for (uint i = 0; i < mCellsW.count(); ++i) {
mCellsW[i]->updateConfig(KOPrefs::instance()->mMonthViewUsesBigFont);
}
#ifdef DESKTOP_VERSION
MonthViewCell::toolTipGroup()->setEnabled(KOPrefs::instance()->mEnableToolTips);
#endif
updateView();
}
void KOMonthView::updateDayLabels()
{
QPtrVector<QLabel> *mDayLabelsT;
mDayLabelsT = &mDayLabelsW;
for (int i = 0; i < 7; i++) {
{
bool show = mShortDayLabelsW;
if ( i > 4 && mShowSatSunComp && mWidthLongDayLabel > (*mDayLabelsT)[i]->width() )
show = true;
(*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i+1,show));
}
}
mDayLabelsT = &mDayLabels;
for (int i = 0; i < 7; i++) {
if (KGlobal::locale()->weekStartsMonday() || KOPrefs::instance()->mMonthViewSatSunTog ) {
bool show = mShortDayLabelsM;
if ( i > 4 && mShowSatSunComp && mWidthLongDayLabel > (*mDayLabelsT)[i]->width() )
show = true;
(*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i+1,show));
} else {
if (i==0) (*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(7,mShortDayLabelsM));
else (*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i,mShortDayLabelsM));
}
}
}
void KOMonthView::showDates(const QDate &start, const QDate &)
{
// kdDebug() << "KOMonthView::showDates(): " << start.toString() << endl;
QPtrVector<MonthViewCell> *cells;
QPtrVector<QLabel> *dayLabels;
QPtrVector<KOWeekButton> *weekLabels;
int weekNum = 6;
mStartDate = start;
if ( mShowWeekView ) {
weekNum = 1;
cells = &mCellsW;
dayLabels = &mDayLabelsW;
weekLabels = &mWeekLabelsW;
if ( !KGlobal::locale()->weekStartsMonday() ) {
mStartDate = mStartDate.addDays( 1 );
}
} else {
cells = &mCells;
dayLabels = &mDayLabels;
weekLabels = &mWeekLabels;
}
int mWeekStartsMonday = KGlobal::locale()->weekStartsMonday();
if ( mShowWeekView || KOPrefs::instance()->mMonthViewSatSunTog ) {
mWeekStartsMonday = true;
}
int startWeekDay = mWeekStartsMonday ? 1 : 7;
while( KOGlobals::self()->calendarSystem()->dayOfWeek(mStartDate) != startWeekDay ) {
mStartDate = mStartDate.addDays( -1 );
}
bool primary = false;
uint i;
for( i = 0; i < (*cells).size(); ++i ) {
QDate date = mStartDate.addDays( i );
(*cells)[i]->setDate( date );
#ifndef KORG_NOPLUGINS
// add holiday, if present
QString hstring(KOCore::self()->holiday(date));
(*cells)[i]->setHoliday( hstring );
#endif
}
QDate date = mStartDate.addDays( mWeekStartsMonday ? 3 : 4 );
for( i = 0; i < weekNum; ++i ) {
int wno;
// remember, according to ISO 8601, the first week of the year is the
// first week that contains a thursday. Thus we must subtract off 4,
// not just 1.
int dayOfYear = date.dayOfYear();
if (dayOfYear % 7 != 0)
wno = dayOfYear / 7 + 1;
else
wno =dayOfYear / 7;
(*weekLabels)[i]->setWeekNum( wno );
date = date.addDays( 7 );
}
updateView();
}
void KOMonthView::showEvents(QPtrList<Event>)
{
qDebug("KOMonthView::selectEvents is not implemented yet. ");
}
void KOMonthView::changeEventDisplay(Event *, int)
{
// this should be re-written to be much more efficient, but this
// quick-and-dirty-hack gets the job done for right now.
updateView();
}
void KOMonthView::updateView()
{
if ( !updatePossible )
return;
//qDebug("UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU ");
//QTime ti;
//ti.start();
clearSelection();
QPtrVector<MonthViewCell> *cells;
if ( mShowWeekView ) {
cells = &mCellsW;
} else {
cells = &mCells;
}
#if 1
int i;
int timeSpan = (*cells).size()-1;
if ( KOPrefs::instance()->mMonthViewWeek )
timeSpan = 6;
for( i = 0; i < timeSpan + 1; ++i ) {
(*cells)[i]->startUpdateCell();
}
QPtrList<Event> events = calendar()->events();
Event *event;
QDateTime dt;
bool ok;
QDate endDate = mStartDate.addDays( timeSpan );
for( event = events.first(); event; event = events.next() ) { // for event
if ( event->doesRecur() ) {
bool last;
QDateTime incidenceStart = event->recurrence()->getPreviousDateTime( QDateTime( mStartDate ) , &last );
QDateTime incidenceEnd;
int eventlen = event->dtStart().date().daysTo ( event->dtEnd().date() );
bool invalid = false;
while( true ) {
if ( incidenceStart.isValid() ) {
incidenceEnd = incidenceStart.addDays( eventlen );
int st = incidenceStart.date().daysTo( endDate );
if ( st >= 0 ) { // start before timeend
int end = mStartDate.daysTo( incidenceEnd.date() );
if ( end >= 0 ) { // end after timestart --- got one!
//normalize
st = timeSpan - st;
if ( st < 0 ) st = 0;
if ( end > timeSpan ) end = timeSpan;
int iii;
//qDebug("found %s %d %d ",event->summary().latin1(), st, end );
for ( iii = st;iii<= end;++iii)
(*cells)[iii]->insertEvent( event );
}
}
} else {
if ( invalid )
break;
invalid = true;
//qDebug("invalid %s", event->summary().latin1());
incidenceStart = QDateTime( mStartDate ).addSecs( -2 );;
}
if ( last )
break;
bool ok;
incidenceStart = event->getNextOccurence( incidenceStart.addSecs( 1 ) ,&ok );
if ( ! ok )
break;
if ( incidenceStart.date() > endDate )
break;
}
} else { // no recur
int st = event->dtStart().date().daysTo( endDate );
if ( st >= 0 ) { // start before timeend
int end = mStartDate.daysTo( event->dtEnd().date() );
if ( end >= 0 ) { // end after timestart --- got one!
//normalize
st = timeSpan - st;
if ( st < 0 ) st = 0;
if ( end > timeSpan ) end = timeSpan;
int iii;
for ( iii = st;iii<= end;++iii)
(*cells)[iii]->insertEvent( event );
}
}
}
}
// insert due todos
QPtrList<Todo> todos = calendar()->todos( );
Todo *todo;
for(todo = todos.first(); todo; todo = todos.next()) {
//insertTodo( todo );
if ( todo->hasDueDate() ) {
int day = mStartDate.daysTo( todo->dtDue().date() );
if ( day >= 0 && day < timeSpan + 1) {
(*cells)[day]->insertTodo( todo );
}
}
}
for( i = 0; i < timeSpan+1; ++i ) {
(*cells)[i]->finishUpdateCell();
}
processSelectionChange();
//qApp->processEvents();
for( i = 0; i < timeSpan+1; ++i ) {
(*cells)[i]->repaintfinishUpdateCell();
}
setKeyBFocus();
#else
// old code
//qDebug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
int i;
for( i = 0; i < (*cells).count(); ++i ) {
(*cells)[i]->updateCell();
}
//qDebug("KOMonthView::updateView() ");
processSelectionChange();
// qDebug("---------------------------------------------------------------------+ ");
(*cells)[0]->setFocus();
#endif
//qDebug("update time %d ", ti.elapsed());
}
void KOMonthView::setKeyBoardFocus()
{
bool shootAgain = false;
if ( mShowWeekView ) {
shootAgain = !mWeekLabelsW[0]->hasFocus();
mWeekLabelsW[0]->setFocus();
}
else {
shootAgain = !mWeekLabels[0]->hasFocus();
mWeekLabels[0]->setFocus();
}
if ( shootAgain ) {
QTimer::singleShot( 0, this, SLOT ( setKeyBFocus() ) );
}
}
void KOMonthView::setKeyBFocus()
{
//qDebug("KOMonthView::setKeyBFocus() ");
QTimer::singleShot( 0, this, SLOT ( setKeyBoardFocus() ) );
}
void KOMonthView::resizeEvent(QResizeEvent * e)
{
//qDebug("KOMonthView::resizeEvent %d %d -- %d %d ", e->size().width(), e->size().height(), e->oldSize().width(), e->oldSize().height());
if ( isVisible() ) {
//qDebug("KOMonthView::isVisible ");
slotComputeLayout();
} else
mComputeLayoutTimer->start( 100 );
}
void KOMonthView::slotComputeLayout()
{
mComputeLayoutTimer->stop();
//qDebug("KOMonthView::Post - resizeEvent %d %d ", width(), height() );
computeLayout();
clPending = true;
setKeyBFocus();
}
void KOMonthView::computeLayoutWeek()
{
static int lastWid = 0;
static int lastHei = 0;
int daysToShow;
bool combinedSatSun = false;
if (mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ) {
daysToShow = 6;
combinedSatSun = true;
}
int tWid = topLevelWidget()->size().width();
int tHei = topLevelWidget()->size().height();
int wid = width();//e
int hei = height()-1-mNavigatorBar->height();
if ( ((wid *3)/2) < tWid && (( hei *3) /2) < tHei )
return;
if ( lastWid == width() && lastHei == height() ) {
//qDebug("KOListWeekView::No compute layout needed ");
return;
}
lastWid = width();
lastHei = height();
if ( wid < hei )
daysToShow = 2;
else
daysToShow = 3;
mShowSatSunComp = true;
combinedSatSun = true;
//qDebug("KOMonthView::computeLayout() WWW ------------------------------------ ");
QFontMetrics fm ( mWeekLabels[0]->font() );
int weeklabelwid = fm.width( "888" );
wid -= weeklabelwid;
int colWid = wid / daysToShow;
int lastCol = wid - ( colWid*6 );
int dayLabelHei = mDayLabelsW[0]->sizeHint().height();
int cellHei = (hei - (5- daysToShow )*dayLabelHei) /(5- daysToShow );
int colModulo = wid % daysToShow;
int rowModulo = (hei- (5- daysToShow )*dayLabelHei) % daysToShow-1;
//qDebug("rowmod %d ", rowModulo);
int i;
int x,y,w,h;
x= 0;
y= 0;
w = colWid;
h = dayLabelHei ;
for ( i = 0; i < 7; i++) {
if ( i && !( i % daysToShow) && i < 6) {
y += hei/(5-daysToShow);
x = 0;
w = colWid;
}
if ( ((i) % daysToShow) >= daysToShow-colModulo ) {
++w;
}
if ( i >= 5 ) {
mDayLabelsW[i]->setGeometry( x+weeklabelwid,y,w/2+w%2,h);
x -= (w/2 );
}
else
mDayLabelsW[i]->setGeometry( x+weeklabelwid,y,w,h);
x += w;
}
x= 0;
y= dayLabelHei;
w = colWid;
h = cellHei;
int max = 0;
for ( i = 0; i < mCellsW.count(); ++i) {
if ( i > 6 ) {
mCellsW[i]->hide();
continue;
}
w = colWid;
if ( ((i) % daysToShow) >= daysToShow-colModulo ) {
++w;
}
if ( i == (daysToShow-1-rowModulo)*7)
++h;
if ( i >= 5 ) {
if ( i ==5 ) {
max = h/2;
mCellsW[i]->setGeometry ( x+weeklabelwid,y,w,max );
x -= w ;y += h/2;
} else {
if ( ((i-1) % daysToShow) >= daysToShow-colModulo ) {
++w;
}
max = h-h/2;
mCellsW[i]->setGeometry ( x+weeklabelwid,y,w,max );
y -= h/2;
}
} else {
max = h;
mCellsW[i]->setGeometry ( x+weeklabelwid,y,w,h );
}
x += w;
if ( x + w/2 > wid ) {
x = 0;
y += h+dayLabelHei ;
}
//mCellsW[i]->dateLabel()->setMaximumHeight( max - mCellsW[i]->lineWidth()*2 );
}
y= dayLabelHei;
h = cellHei ;
mWeekLabelsW[0]->setGeometry( 0,y,weeklabelwid,hei-dayLabelHei);
mWeekLabelsW[1]->setGeometry( 0,0,weeklabelwid,dayLabelHei);
// qDebug("RRRRRRRRRRRRR %d %d old %d %d", e->size().width(),e->size().height() , e->oldSize().width(),e->oldSize().height());
//qDebug("parent %d %d ", topLevelWidget()->size().width(), topLevelWidget()->size().height());
mShortDayLabelsW = mDayLabelsW[0]->width()-2 < mWidthLongDayLabel ;
updateDayLabels();
//bool forceUpdate = !updatePossible;
updatePossible = true;
//mWeekLabels[mNumWeeks]->setText( i18n("M"));
//if ( forceUpdate )
// updateView();
}
void KOMonthView::computeLayout()
{
static int lastWid = 0;
static int lastHei = 0;
if ( mShowWeekView ){
computeLayoutWeek();
return;
}
int daysToShow = 7;
bool combinedSatSun = false;
if (mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ) {
daysToShow = 6;
combinedSatSun = true;
}
int tWid = topLevelWidget()->size().width();
int tHei = topLevelWidget()->size().height();
int wid = width();//e
int hei = height()-1-mNavigatorBar->height();
if ( ((wid *3)/2) < tWid && (( hei *3) /2) < tHei ) {
return;
}
if ( lastWid == width() && lastHei == height() ){
//qDebug("KOMonthview::No compute layout needed ");
return;
}
lastWid = width();
lastHei = height();
//qDebug("KOMonthView::computeLayout() MMM ------------------- ");
QFontMetrics fm ( mWeekLabels[0]->font() );
int weeklabelwid = fm.width( "888" );
wid -= weeklabelwid;
int colWid = wid / daysToShow;
int lastCol = wid - ( colWid*6 );
int dayLabelHei = mDayLabels[0]->sizeHint().height();
int cellHei = (hei - dayLabelHei) /6;
int colModulo = wid % daysToShow;
int rowModulo = (hei- dayLabelHei) % 6;
//qDebug("rowmod %d ", rowModulo);
int i;
int x,y,w,h;
x= 0;
y= 0;
w = colWid;
h = dayLabelHei ;
for ( i = 0; i < 7; i++) {
if ( i == daysToShow-colModulo )
++w;
if ( combinedSatSun ) {
if ( i >= daysToShow-1 ) {
mDayLabels[i]->setGeometry( x+weeklabelwid,y,w/2,h);
x -= w/2 ;
}
else
mDayLabels[i]->setGeometry( x+weeklabelwid,y,w,h);
} else
mDayLabels[i]->setGeometry( x+weeklabelwid,y,w,h);
x += w;
}
x= 0;
y= dayLabelHei;
w = colWid;
h = cellHei ;
int max = 0;
for ( i = 0; i < mCells.count(); ++i) {
//qDebug("iii %d ", i);
w = colWid;
if ( ((i) % 7) >= 7-colModulo ) {
++w;
}
if ( i == (6-rowModulo)*7)
++h;
if ( combinedSatSun ) {
if ( (i)%7 >= daysToShow-1 ) {
if ( (i)%7 == daysToShow-1 ) {
max = h/2;
mCells[i]->setGeometry ( x+weeklabelwid,y,w,max );
x -= w ;y += h/2;
} else {
max = h-h/2;
mCells[i]->setGeometry ( x+weeklabelwid,y,w,max );
y -= h/2;
}
} else {
max = h;
mCells[i]->setGeometry ( x+weeklabelwid,y,w,h );
}
}
else {
max = h;
mCells[i]->setGeometry ( x+weeklabelwid,y,w,h );
}
x += w;
if ( x + w/2 > wid ) {
x = 0;
y += h;
}
//mCells[i]->dateLabel()->setMaximumHeight( max- mCells[i]->lineWidth()*2 );
}
y= dayLabelHei;
h = cellHei ;
for ( i = 0; i < 6; i++) {
if ( i == (6-rowModulo))
++h;
mWeekLabels[i]->setGeometry( 0,y,weeklabelwid,h);
y += h;
}
mWeekLabels[6]->setGeometry( 0,0,weeklabelwid,dayLabelHei);
// qDebug("RRRRRRRRRRRRR %d %d old %d %d", e->size().width(),e->size().height() , e->oldSize().width(),e->oldSize().height());
//qDebug("parent %d %d ", topLevelWidget()->size().width(), topLevelWidget()->size().height());
mShortDayLabelsM = mDayLabels[0]->width()-2 < mWidthLongDayLabel ;
updateDayLabels();
//bool forceUpdate = !updatePossible;
updatePossible = true;
//mWeekLabels[mNumWeeks]->setText( i18n("W"));
}
void KOMonthView::showContextMenu( Incidence *incidence )
{
mContextMenu->showIncidencePopup(incidence);
/*
if( incidence && incidence->type() == "Event" ) {
Event *event = static_cast<Event *>(incidence);
mContextMenu->showEventPopup(event);
} else {
kdDebug() << "MonthView::showContextMenu(): cast failed." << endl;
}
*/
}
MonthViewCell * KOMonthView::selectedCell( )
{
return mSelectedCell;
}
void KOMonthView::setSelectedCell( MonthViewCell *cell )
{
//qDebug("KOMonthView::setSelectedCell ");
if ( mSelectedCell && mSelectedCell != cell ) {
MonthViewCell * mvc = mSelectedCell;
mSelectedCell = cell;
mvc->deselect();
} else
mSelectedCell = cell;
// if ( mSelectedCell )
// mSelectedCell->select();
if ( !mSelectedCell )
emit incidenceSelected( 0 );
else
emit incidenceSelected( mSelectedCell->selectedIncidence() );
}
void KOMonthView::processSelectionChange()
{
QPtrList<Incidence> incidences = selectedIncidences();
if (incidences.count() > 0) {
emit incidenceSelected( incidences.first() );
} else {
emit incidenceSelected( 0 );
clearSelection();
}
}
void KOMonthView::clearSelection()
{
if ( mSelectedCell ) {
mSelectedCell->deselect();
mSelectedCell = 0;
}
}
+
+void KOMonthView::keyReleaseEvent ( QKeyEvent * e)
+{
+ if ( !e->isAutoRepeat() ) {
+ mFlagKeyPressed = false;
+ }
+}
+
void KOMonthView::keyPressEvent ( QKeyEvent * e )
{
- //qDebug("KOMonthView::keyPressEvent ");
+
+ qApp->processEvents();
+ if ( e->isAutoRepeat() && !mFlagKeyPressed ) {
+ //e->ignore();
+ e->accept();
+ return;
+ }
+ if (! e->isAutoRepeat() )
+ mFlagKeyPressed = true;
switch(e->key()) {
case Key_Up:
{
if ( mShowWeekView ) {
emit selectWeekNum ( currentWeek() - 1 );
}
else {
emit prevMonth();
}
}
e->accept();
break;
case Key_Down:
{
if ( mShowWeekView ) {
emit selectWeekNum ( currentWeek() +1);
}
else {
emit nextMonth();
}
}
e->accept();
break;
case Key_Return:
case Key_Enter:
{
selectInternalWeekNum ( currentWeek() );
}
e->accept();
break;
case Key_D:
if ( mSelectedCell ) {
mSelectedCell->showDay();
e->accept();
} else {
e->ignore();
}
break;
default:
e->ignore();
break;
}
}
diff --git a/korganizer/komonthview.h b/korganizer/komonthview.h
index c1ca3d4..88050fe 100644
--- a/korganizer/komonthview.h
+++ b/korganizer/komonthview.h
@@ -1,320 +1,321 @@
/*
This file is part of KOrganizer.
Copyright (c) 2000,2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _KOMONTHVIEW_H
#define _KOMONTHVIEW_H
#include <qlabel.h>
#include <qframe.h>
#include <qdatetime.h>
#include <qlistbox.h>
#include <qpoint.h>
#include <qwidgetstack.h>
#include <qlayout.h>
#include <qtimer.h>
#include <qintdict.h>
#include <qpushbutton.h>
#include <qvaluelist.h>
#include <qptrvector.h>
#include <libkcal/calendar.h>
#include <libkcal/event.h>
#include "koeventview.h"
#include "navigatorbar.h"
#ifdef DESKTOP_VERSION
class QToolTipGroup;
#endif
class KNOWhatsThis;
class KOWeekButton : public QPushButton
{
Q_OBJECT
public:
KOWeekButton( QWidget *parent=0, const char *name=0 ) :
QPushButton( parent, name)
{
connect( this, SIGNAL( clicked() ),
SLOT( bottonClicked() ));
mNumber = -1;
}
void setWeekNum ( int num ) {mNumber = num; setText( QString::number ( num ));}
int getWeekNum() { return mNumber;}
signals:
void selectWeekNum ( int );
private:
int mNumber;
void keyPressEvent ( QKeyEvent * e )
{
e->ignore();
}
private slots :
void bottonClicked() { if ( mNumber > 0 ) emit selectWeekNum ( mNumber ); }
};
class KNoScrollListBox: public QListBox
{
Q_OBJECT
public:
KNoScrollListBox(QWidget *parent=0, const char *name=0);
~KNoScrollListBox();
QString getWhatsThisText(QPoint p) ;
signals:
void shiftDown();
void shiftUp();
void rightClick();
protected slots:
void oneDown();
void keyPressEvent(QKeyEvent *);
void keyReleaseEvent(QKeyEvent *);
void mousePressEvent(QMouseEvent *);
private:
KNOWhatsThis * mWT;
};
class MonthViewItem: public QListBoxItem
{
public:
MonthViewItem( Incidence *, QDate qd, const QString & title );
void recycle( Incidence *incidence, QDate qd, const QString & s);
void setRecur(bool on) { mRecur = on; }
void setAlarm(bool on) { mAlarm = on; }
void setReply(bool on) { mReply = on; }
void setMoreInfo(bool on) { mInfo = on; }
void setMultiDay(int type) { mMultiday = type; }
void setBlockRepaint(bool on) { mblockRepaint = on; }
void setPalette(const QPalette &p) { mPalette = p; }
QPalette palette() const { return mPalette; }
Incidence *incidence() const { return mIncidence; }
QDate incidenceDate() { return mDate; }
protected:
virtual void paint(QPainter *);
virtual int height(const QListBox *) const;
virtual int width(const QListBox *) const;
private:
bool mblockRepaint;
int mMultiday;
bool mRecur;
bool mAlarm;
bool mReply;
bool mInfo;
QPalette mPalette;
QDate mDate;
Incidence *mIncidence;
};
class KOMonthView;
class MonthViewCell : public KNoScrollListBox
{
Q_OBJECT
public:
MonthViewCell(KOMonthView *,QWidget* );
~MonthViewCell() {mAvailItemList.setAutoDelete( true );}
void setDate( const QDate & );
QDate date() const;
void setPrimary( bool );
bool isPrimary() const;
void setHoliday( bool );
void setHoliday( const QString & );
void updateCell();
void startUpdateCell();
void finishUpdateCell();
void repaintfinishUpdateCell();
void insertEvent(Event *);
void insertTodo(Todo *);
void updateConfig( bool bigFont = false );
void enableScrollBars( bool );
Incidence *selectedIncidence();
QDate selectedIncidenceDate();
QPushButton * dateLabel() { return mLabel; }
void deselect();
void select();
#ifdef DESKTOP_VERSION
static QToolTipGroup *toolTipGroup();
#endif
signals:
void defaultAction( Incidence * );
void newEventSignal( QDateTime );
void showDaySignal( QDate );
protected:
QStringList mToolTip;
void resizeEvent( QResizeEvent * );
public slots:
void showDay();
protected slots:
void defaultAction( QListBoxItem * );
void contextMenu( QListBoxItem * );
void selection( QListBoxItem * );
void cellClicked( QListBoxItem * );
void newEvent();
private:
MonthViewItem* mCurrentAvailItem;
QPtrList <MonthViewItem> mAvailItemList;
KOMonthView *mMonthView;
int currentPalette;
QDate mDate;
bool mPrimary;
bool mHoliday;
QString mHolidayString;
//QLabel *mLabel;
QPushButton *mLabel;
//QListBox *mItemList;
#ifdef DESKTOP_VERSION
static QToolTipGroup *mToolTipGroup;
#endif
QSize mLabelSize;
QSize mLabelBigSize;
QPalette mHolidayPalette;
QPalette mStandardPalette;
QPalette mPrimaryPalette;
QPalette mNonPrimaryPalette;
void setMyPalette();
QPalette getPalette ();
};
class KOMonthView: public KOEventView
{
Q_OBJECT
public:
KOMonthView(Calendar *cal, QWidget *parent = 0, const char *name = 0 );
~KOMonthView();
/** Returns maximum number of days supported by the komonthview */
virtual int maxDatesHint();
/** Returns number of currently shown dates. */
virtual int currentDateCount();
/** returns the currently selected events */
virtual QPtrList<Incidence> selectedIncidences();
/** returns dates of the currently selected events */
virtual DateList selectedDates();
virtual void printPreview(CalPrinter *calPrinter,
const QDate &, const QDate &);
bool isMonthView() { return !mShowWeekView; }
bool isUpdatePossible() { return updatePossible; }
MonthViewCell * selectedCell();
bool skipResize;
NavigatorBar* navigatorBar() { return mNavigatorBar ;}
public slots:
virtual void updateView();
virtual void updateConfig();
virtual void showDates(const QDate &start, const QDate &end);
virtual void showEvents(QPtrList<Event> eventList);
void changeEventDisplay(Event *, int);
void clearSelection();
void showContextMenu( Incidence * );
void setSelectedCell( MonthViewCell * );
void switchView();
void setKeyBoardFocus();
void setKeyBFocus();
protected slots:
void slotComputeLayout();
void selectInternalWeekNum ( int );
void processSelectionChange();
signals:
void nextMonth();
void prevMonth();
void selectWeekNum ( int );
void selectMonth ();
void showDaySignal( QDate );
protected:
void resizeEvent(QResizeEvent *);
void viewChanged();
void updateDayLabels();
private:
QTimer* mComputeLayoutTimer;
NavigatorBar* mNavigatorBar;
int currentWeek();
bool clPending;
QWidgetStack * mWidStack;
QWidget* mMonthView;
QWidget* mWeekView;
bool mShowWeekView;
bool updatePossible;
int mDaysPerWeek;
int mNumWeeks;
int mNumCells;
//bool mWeekStartsMonday;
bool mShowSatSunComp;
void computeLayout();
void computeLayoutWeek();
QPtrVector<MonthViewCell> mCells;
QPtrVector<QLabel> mDayLabels;
QPtrVector<KOWeekButton> mWeekLabels;
QPtrVector<MonthViewCell> mCellsW;
QPtrVector<QLabel> mDayLabelsW;
QPtrVector<KOWeekButton> mWeekLabelsW;
bool mShortDayLabelsM;
bool mShortDayLabelsW;
int mWidthLongDayLabel;
QDate mStartDate;
MonthViewCell *mSelectedCell;
-
+ bool mFlagKeyPressed;
KOEventPopupMenu *mContextMenu;
void keyPressEvent ( QKeyEvent * ) ;
+ void keyReleaseEvent ( QKeyEvent * ) ;
};
#endif
diff --git a/korganizer/mainwindow.cpp b/korganizer/mainwindow.cpp
index ae03a09..09a0880 100644
--- a/korganizer/mainwindow.cpp
+++ b/korganizer/mainwindow.cpp
@@ -1,716 +1,727 @@
#include <stdlib.h>
#include <qaction.h>
#include <qpopupmenu.h>
#include <qpainter.h>
#include <qwhatsthis.h>
#include <qpushbutton.h>
#include <qmessagebox.h>
#include <qlineedit.h>
#include <qtextcodec.h>
#include <qfile.h>
#include <qdir.h>
#include <qapp.h>
#include <qfileinfo.h>
#include <qlabel.h>
#include <qspinbox.h>
#include <qcheckbox.h>
#include <qmap.h>
#include <qwmatrix.h>
#include <qtextbrowser.h>
#include <qtextstream.h>
#ifndef DESKTOP_VERSION
#include <qpe/global.h>
#include <qpe/qpemenubar.h>
#include <qpe/qpetoolbar.h>
#include <qpe/resource.h>
#include <qpe/qpeapplication.h>
#include <qtopia/alarmserver.h>
#include <qtopia/qcopenvelope_qws.h>
#include <unistd.h> // for sleep
#else
#include <qmenubar.h>
#include <qtoolbar.h>
#include <qapplication.h>
//#include <resource.h>
#endif
#include <libkcal/calendarlocal.h>
#include <libkcal/todo.h>
#include <libkcal/phoneformat.h>
#include <libkdepim/ksyncprofile.h>
#include <libkdepim/phoneaccess.h>
#include <libkcal/kincidenceformatter.h>
#include <libkdepim/kpimglobalprefs.h>
#include "calendarview.h"
#include "koviewmanager.h"
#include "datenavigator.h"
#include "koagendaview.h"
#include "koagenda.h"
#include "kodialogmanager.h"
#include "kdialogbase.h"
#include "kapplication.h"
#include "kofilterview.h"
#include "kstandarddirs.h"
#include "koprefs.h"
#include "kfiledialog.h"
#include "koglobals.h"
#include "kglobal.h"
#include "ktoolbar.h"
#include "klocale.h"
#include "kconfig.h"
#include "simplealarmclient.h"
#include "externalapphandler.h"
using namespace KCal;
#ifndef _WIN32_
#include <unistd.h>
#else
#ifdef _OL_IMPORT_
#include "koimportoldialog.h"
#endif
#endif
#include "mainwindow.h"
class KOex2phonePrefs : public QDialog
{
public:
KOex2phonePrefs( QWidget *parent=0, const char *name=0 ) :
QDialog( parent, name, true )
{
setCaption( i18n("Export to phone options") );
QVBoxLayout* lay = new QVBoxLayout( this );
lay->setSpacing( 3 );
lay->setMargin( 3 );
QLabel *lab;
lay->addWidget(lab = new QLabel( i18n("Please read Help-Sync Howto\nto know what settings to use."), this ) );
lab->setAlignment (AlignHCenter );
QHBox* temphb;
temphb = new QHBox( this );
new QLabel( i18n("I/O device: "), temphb );
mPhoneDevice = new QLineEdit( temphb);
lay->addWidget( temphb );
temphb = new QHBox( this );
new QLabel( i18n("Connection: "), temphb );
mPhoneConnection = new QLineEdit( temphb);
lay->addWidget( temphb );
temphb = new QHBox( this );
new QLabel( i18n("Model(opt.): "), temphb );
mPhoneModel = new QLineEdit( temphb);
lay->addWidget( temphb );
mWriteBackFuture= new QCheckBox( i18n("Write back events in future only"), this );
mWriteBackFuture->setChecked( true );
lay->addWidget( mWriteBackFuture );
temphb = new QHBox( this );
new QLabel( i18n("Max. weeks in future: ") , temphb );
mWriteBackFutureWeeks= new QSpinBox(1,104, 1, temphb);
mWriteBackFutureWeeks->setValue( 8 );
lay->addWidget( temphb );
lay->addWidget(lab = new QLabel( i18n("NOTE: This will remove all old\ntodo/calendar data on phone!"), this ) );
lab->setAlignment (AlignHCenter );
QPushButton * ok = new QPushButton( i18n("Export to mobile phone!"), this );
lay->addWidget( ok );
QPushButton * cancel = new QPushButton( i18n("Cancel"), this );
lay->addWidget( cancel );
connect ( ok,SIGNAL(clicked() ),this , SLOT ( accept() ) );
connect (cancel, SIGNAL(clicked() ), this, SLOT ( reject()) );
resize( 220, 240 );
qApp->processEvents();
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
move( (dw-width())/2, (dh - height() )/2 );
}
public:
QLineEdit* mPhoneConnection, *mPhoneDevice, *mPhoneModel;
QCheckBox* mWriteBackFuture;
QSpinBox* mWriteBackFutureWeeks;
};
int globalFlagBlockStartup;
MainWindow::MainWindow( QWidget *parent, const char *name, QString msg) :
QMainWindow( parent, name )
{
mClosed = false;
//QString confFile = KStandardDirs::appDir() + "config/korganizerrc";
QString confFile = locateLocal("config","korganizerrc");
QFileInfo finf ( confFile );
bool showWarning = !finf.exists();
setIcon(SmallIcon( "ko24" ) );
mBlockAtStartup = true;
mFlagKeyPressed = false;
setCaption("KO/Pi");
KOPrefs *p = KOPrefs::instance();
KPimGlobalPrefs::instance()->setGlobalConfig();
if ( p->mHourSize > 22 )
p->mHourSize = 22;
QMainWindow::ToolBarDock tbd;
if ( p->mToolBarHor ) {
if ( p->mToolBarUp )
tbd = Bottom;
else
tbd = Top;
}
else {
if ( p->mToolBarUp )
tbd = Right;
else
tbd = Left;
}
if ( KOPrefs::instance()->mUseAppColors )
QApplication::setPalette( QPalette (KOPrefs::instance()->mAppColor1, KOPrefs::instance()->mAppColor2), true );
globalFlagBlockStartup = 1;
iconToolBar = new QPEToolBar( this );
addToolBar (iconToolBar , tbd );
- if ( KOPrefs::instance()->mShowIconFilter ) {
+#ifdef DESKTOP_VERSION
+ if ( KOPrefs::instance()->mShowIconFilter )
+#else
+ if ( KOPrefs::instance()->mShowIconFilter || !p->mShowIconOnetoolbar )
+#endif
+
+{
if ( p->mToolBarHorF ) {
if ( p->mToolBarUpF )
tbd = Bottom;
else
tbd = Top;
}
else {
if ( p->mToolBarUpF )
tbd = Right;
else
tbd = Left;
}
filterToolBar = new QPEToolBar ( this );
filterMenubar = new QPEMenuBar( filterToolBar );
QFontMetrics fm ( filterMenubar->font() );
filterPopupMenu = new QPopupMenu( this );
filterMenubar->insertItem( i18n("No Filter"), filterPopupMenu,0 );
QString addTest = "Ax";
#ifdef DESKTOP_VERSION
addTest = "AAAx";
#endif
filterMenubar->setFixedWidth( fm.width( i18n("No Filter")+addTest ) );
addToolBar (filterToolBar , tbd );
connect ( filterPopupMenu , SIGNAL( activated ( int ) ), this, SLOT (selectFilterPopup( int ) ) );
connect ( filterPopupMenu , SIGNAL( aboutToShow() ), this, SLOT (fillFilterMenuPopup() ) );
+ if ( !KOPrefs::instance()->mShowIconFilter && !p->mShowIconOnetoolbar )
+ filterToolBar->hide();
} else {
filterToolBar = 0;
filterMenubar = 0;
filterPopupMenu = 0;
}
if ( p->mShowIconOnetoolbar ) {
viewToolBar = iconToolBar ;
navigatorToolBar = iconToolBar ;
} else {
+#ifndef DESKTOP_VERSION
+ setToolBarsMovable( false );
+#endif
if ( p->mToolBarHorV ) {
if ( p->mToolBarUpV )
tbd = Bottom;
else
tbd = Top;
}
else {
if ( p->mToolBarUpV )
tbd = Right;
else
tbd = Left;
}
viewToolBar = new QPEToolBar( this );
addToolBar (viewToolBar , tbd );
if ( p->mToolBarHorN ) {
if ( p->mToolBarUpN )
tbd = Bottom;
else
tbd = Top;
}
else {
if ( p->mToolBarUpN )
tbd = Right;
else
tbd = Left;
}
navigatorToolBar = new QPEToolBar( this );
addToolBar (navigatorToolBar , tbd );
}
mCalendarModifiedFlag = false;
QLabel* splash = new QLabel(i18n("KO/Pi is starting ... "), this );
splash->setAlignment ( AlignCenter );
setCentralWidget( splash );
#ifndef DESKTOP_VERSION
showMaximized();
#endif
//qDebug("Mainwidget x %d y %d w %d h %d", x(), y(), width(), height ());
setDefaultPreferences();
mCalendar = new CalendarLocal();
mView = new CalendarView( mCalendar, this,"mCalendar " );
mView->hide();
//mView->resize(splash->size() );
initActions();
mSyncManager = new KSyncManager((QWidget*)this, (KSyncInterface*)mView, KSyncManager::KOPI, KOPrefs::instance(), syncMenu);
mSyncManager->setBlockSave(false);
mView->setSyncManager(mSyncManager);
#ifndef DESKTOP_VERSION
iconToolBar->show();
qApp->processEvents();
#endif
//qDebug("Splashwidget x %d y %d w %d h %d", splash-> x(), splash->y(), splash->width(),splash-> height ());
int vh = height() ;
int vw = width();
//qDebug("Toolbar hei %d ",iconToolBar->height() );
if ( iconToolBar->orientation () == Qt:: Horizontal ) {
vh -= iconToolBar->height();
} else {
vw -= iconToolBar->height();
}
//mView->setMaximumSize( splash->size() );
//mView->resize( splash->size() );
//qDebug("MainView x %d y %d w %d h %d", mView->x(),mView-> y(), mView->width(), mView->height ());
mView->readSettings();
bool newFile = false;
if( !QFile::exists( defaultFileName() ) ) {
QFileInfo finfo ( defaultFileName() );
QString oldFile = QDir::convertSeparators( QDir::homeDirPath()+"/Applications/korganizer/mycalendar.ics");
qDebug("oldfile %s ", oldFile.latin1());
QString message = "You are starting KO/Pi for the\nfirst time after updating to a\nversion >= 1.9.1. The location of the\ndefault calendar file has changed.\nA mycalendar.ics file was detected\nat the old location.\nThis file will be loaded now\nand stored at the new location!\n(Config file location has changed, too!)\nPlease read menu Help-What's New!\n";
finfo.setFile( oldFile );
if (finfo.exists() ) {
KMessageBox::information( this, message);
mView->openCalendar( oldFile );
qApp->processEvents();
} else {
oldFile = QDir::convertSeparators( QDir::homeDirPath()+"/korganizer/mycalendar.ics");
finfo.setFile( oldFile );
if (finfo.exists() ) {
KMessageBox::information( this, message);
mView->openCalendar( oldFile );
qApp->processEvents();
}
}
mView->saveCalendar( defaultFileName() );
newFile = true;
}
QTime neededSaveTime = QDateTime::currentDateTime().time();
mView->openCalendar( defaultFileName() );
int msNeeded = neededSaveTime.msecsTo( QDateTime::currentDateTime().time() );
qDebug("KO: Calendar loading time: %d ms",msNeeded );
if ( KPimGlobalPrefs::instance()->mPreferredLanguage != KOPrefs::instance()->mOldLoadedLanguage ) {
KOPrefs::instance()->setAllDefaults();
int count = mView->addCategories();
}
processIncidenceSelection( 0 );
connect( mView, SIGNAL( incidenceSelected( Incidence * ) ),
SLOT( processIncidenceSelection( Incidence * ) ) );
connect( mView, SIGNAL( modifiedChanged( bool ) ),
SLOT( slotModifiedChanged( bool ) ) );
connect( mView, SIGNAL( tempDisableBR(bool) ),
SLOT( disableBR(bool) ) );
connect( &mSaveTimer, SIGNAL( timeout() ), SLOT( save() ) );
mView->setModified( false );
mBlockAtStartup = false;
mView->setModified( false );
setCentralWidget( mView );
globalFlagBlockStartup = 0;
mView->show();
delete splash;
if ( newFile )
mView->updateConfig();
// qApp->processEvents();
//qDebug("MainView x %d y %d w %d h %d", mView->x(),mView-> y(), mView->width(), mView->height ());
//fillSyncMenu();
connect(mSyncManager , SIGNAL( save() ), this, SLOT( save() ) );
connect(mView , SIGNAL( save() ), this, SLOT( save() ) );
connect(mView , SIGNAL( saveStopTimer() ), this, SLOT( saveStopTimer() ) );
connect(mSyncManager , SIGNAL( request_file() ), this, SLOT( syncFileRequest() ) );
connect(mSyncManager , SIGNAL( getFile( bool )), this, SLOT(getFile( bool ) ) );
mSyncManager->setDefaultFileName( sentSyncFile());
connect ( syncMenu, SIGNAL( activated ( int ) ), mSyncManager, SLOT (slotSyncMenu( int ) ) );
mSyncManager->fillSyncMenu();
mView->viewManager()->agendaView()->setStartHour( KOPrefs::instance()->mDayBegins );
if ( showWarning ) {
KMessageBox::information( this,
"You are starting KO/Pi for the first time.\nPlease read menu: Help-What's New,\nif you did an update!\nPlease choose your timezone in the \nConfigure Dialog TAB Time Zone!\nPlease choose your language\nin the TAB Locale!\nYou get the Configure Dialog\nvia Menu: Actions - Configure....\nClick OK to show the Configure Dialog!\n", "KO/Pi information");
qApp->processEvents();
mView->dialogManager()->showSyncOptions();
}
//US listen for result adressed from Ka/Pi
#ifndef DESKTOP_VERSION
connect(qApp, SIGNAL (appMessage ( const QCString &, const QByteArray & )), ExternalAppHandler::instance(), SLOT (appMessage ( const QCString &, const QByteArray & )));
#endif
#ifndef DESKTOP_VERSION
infrared = 0;
#endif
updateFilterToolbar();
updateWeek( mView->startDate() );
connect( mView->dateNavigator(), SIGNAL( datesSelected( const KCal::DateList & ) ),
SLOT( updateWeekNum( const KCal::DateList & ) ) );
mBRdisabled = false;
//toggleBeamReceive();
}
MainWindow::~MainWindow()
{
//qDebug("MainWindow::~MainWindow() ");
//save toolbar location
delete mCalendar;
delete mSyncManager;
#ifndef DESKTOP_VERSION
if ( infrared )
delete infrared;
#endif
}
void MainWindow::disableBR(bool b)
{
#ifndef DESKTOP_VERSION
if ( b ) {
if ( infrared ) {
toggleBeamReceive();
mBRdisabled = true;
}
mBRdisabled = true;
} else {
if ( mBRdisabled ) {
mBRdisabled = false;
//makes no sense,because other cal ap is probably running
// toggleBeamReceive();
}
}
#endif
}
bool MainWindow::beamReceiveEnabled()
{
#ifndef DESKTOP_VERSION
return ( infrared != 0 );
#endif
return false;
}
void MainWindow::toggleBeamReceive()
{
if ( mBRdisabled )
return;
#ifndef DESKTOP_VERSION
if ( infrared ) {
qDebug("disable BeamReceive ");
delete infrared;
infrared = 0;
brAction->setOn(false);
return;
}
qDebug("enable BeamReceive ");
brAction->setOn(true);
infrared = new QCopChannel("QPE/Application/datebook",this, "channel" ) ;
QObject::connect( infrared, SIGNAL (received ( const QCString &, const QByteArray & )),this, SLOT(recieve( const QCString&, const QByteArray& )));
#endif
}
void MainWindow::showMaximized ()
{
#ifndef DESKTOP_VERSION
if ( ! globalFlagBlockStartup )
if ( mClosed )
mView->goToday();
#endif
QWidget::showMaximized () ;
mClosed = false;
}
void MainWindow::closeEvent( QCloseEvent* ce )
{
if ( ! KOPrefs::instance()->mAskForQuit ) {
saveOnClose();
mClosed = true;
ce->accept();
return;
}
switch( QMessageBox::information( this, "KO/Pi",
i18n("Do you really want\nto close KO/Pi?"),
i18n("Close"), i18n("No"),
0, 0 ) ) {
case 0:
saveOnClose();
mClosed = true;
ce->accept();
break;
case 1:
ce->ignore();
break;
case 2:
default:
break;
}
}
void MainWindow::recieve( const QCString& cmsg, const QByteArray& data )
{
QDataStream stream( data, IO_ReadOnly );
// QMessageBox::about( this, "About KOrganizer/Pi", "*" +msg +"*" );
//QString datamess;
//qDebug("message ");
qDebug("KO: QCOP message received: %s ", cmsg.data() );
if ( cmsg == "setDocument(QString)" ) {
QDataStream stream( data, IO_ReadOnly );
QString fileName;
stream >> fileName;
//qDebug("filename %s ", fileName.latin1());
showMaximized();
raise();
KOPrefs::instance()->mLastSyncedLocalFile = fileName ;
mSyncManager->slotSyncMenu( 1002 );
return;
}
if ( cmsg == "-writeFile" ) {
// I made from the "-writeFile" an "-writeAlarm"
mView->viewManager()->showWhatsNextView();
mCalendar->checkAlarmForIncidence( 0, true);
showMaximized();
raise();
return;
}
if ( cmsg == "-writeFileSilent" ) {
// I made from the "-writeFile" an "-writeAlarm"
// mView->viewManager()->showWhatsNextView();
mCalendar->checkAlarmForIncidence( 0, true);
//showMaximized();
//raise();
hide();
return;
}
if ( cmsg == "-newCountdown" ) {
qDebug("newCountdown ");
}
QString msg ;
QString allmsg = cmsg;
while ( allmsg.length() > 0 ) {
int nextC = allmsg.find( "-", 1 );
if ( nextC == -1 ) {
msg = allmsg;
allmsg = "";
} else{
msg = allmsg.left( nextC );
allmsg = allmsg.mid( nextC, allmsg.length()-nextC );
}
//qDebug("msg: %s all: %s ", msg.latin1(), allmsg.latin1() );
if ( msg == "-newEvent" ) {
mView->newEvent();
}
if ( msg == "-newTodo" ) {
mView->newTodo();
}
if ( msg == "-showWN" ) {
mView->viewManager()->showWhatsNextView();
}
if ( msg == "-showTodo" ) {
mView->viewManager()->showTodoView();
}
if ( msg == "-showList" ) {
mView->viewManager()->showListView();
}
else if ( msg == "-showDay" ) {
mView->viewManager()->showDayView();
}
else if ( msg == "-showWWeek" ) {
mView->viewManager()->showWorkWeekView();
}
else if ( msg == "-ringSync" ) {
mSyncManager->multiSync( false );
}
else if ( msg == "-showWeek" ) {
mView->viewManager()->showWeekView();
}
else if ( msg == "-showTodo" ) {
mView->viewManager()->showTodoView();
}
else if ( msg == "-showJournal" ) {
mView->dateNavigator()->selectDates( 1 );
mView->dateNavigator()->selectToday();
mView->viewManager()->showJournalView();
}
else if ( msg == "-showKO" ) {
mView->viewManager()->showNextXView();
}
else if ( msg == "-showWNext" ) {
mView->viewManager()->showWhatsNextView();
}
else if ( msg == "nextView()" ) {
mView->viewManager()->showNextView();
}
else if ( msg == "-showNextXView" ) {
mView->viewManager()->showNextXView();
}
}
showMaximized();
raise();
}
QPixmap MainWindow::loadPixmap( QString name )
{
return SmallIcon( name );
}
void MainWindow::initActions()
{
//KOPrefs::instance()->mShowFullMenu
iconToolBar->clear();
KOPrefs *p = KOPrefs::instance();
//QPEMenuBar *menuBar1;// = new QPEMenuBar( iconToolBar );
QPopupMenu *viewMenu = new QPopupMenu( this );
QPopupMenu *actionMenu = new QPopupMenu( this );
QPopupMenu *importMenu = new QPopupMenu( this );
QPopupMenu *importMenu_X = new QPopupMenu( this );
QPopupMenu *exportMenu_X = new QPopupMenu( this );
QPopupMenu *beamMenu_X = new QPopupMenu( this );
selectFilterMenu = new QPopupMenu( this );
selectFilterMenu->setCheckable( true );
syncMenu = new QPopupMenu( this );
configureAgendaMenu = new QPopupMenu( this );
configureToolBarMenu = new QPopupMenu( this );
QPopupMenu *helpMenu = new QPopupMenu( this );
QIconSet icon;
int pixWid = 22, pixHei = 22;
QString pathString = "";
if ( !p->mToolBarMiniIcons ) {
if ( QApplication::desktop()->width() < 480 ) {
pathString += "icons16/";
pixWid = 18; pixHei = 16;
}
} else {
pathString += "iconsmini/";
pixWid = 18; pixHei = 16;
}
if ( KOPrefs::instance()->mShowFullMenu ) {
QMenuBar *menuBar1;
menuBar1 = menuBar();
menuBar1->insertItem( i18n("File"), importMenu );
menuBar1->insertItem( i18n("View"), viewMenu );
menuBar1->insertItem( i18n("Actions"), actionMenu );
#ifdef DESKTOP_VERSION
menuBar1->insertItem( i18n("Synchronize"), syncMenu );
menuBar1->insertItem( i18n("AgendaSize"),configureAgendaMenu );
#else
menuBar1->insertItem( i18n("Sync"), syncMenu );
menuBar1->insertItem( i18n("Agenda"),configureAgendaMenu );
#endif
//menuBar1->insertItem( i18n("Toolbar"),configureToolBarMenu );
menuBar1->insertItem( i18n("Filter"),selectFilterMenu );
menuBar1->insertItem( i18n("Help"), helpMenu );
} else {
QPEMenuBar *menuBar1;
menuBar1 = new QPEMenuBar( iconToolBar );
QPopupMenu *menuBar = new QPopupMenu( this );
icon = loadPixmap( pathString + "z_menu" );
menuBar1->insertItem( icon.pixmap(), menuBar);
//menuBar1->insertItem( i18n("ME"), menuBar);
menuBar->insertItem( i18n("File"), importMenu );
menuBar->insertItem( i18n("View"), viewMenu );
menuBar->insertItem( i18n("Actions"), actionMenu );
menuBar->insertItem( i18n("Synchronize"), syncMenu );
menuBar->insertItem( i18n("AgendaSize"),configureAgendaMenu );
menuBar->insertItem( i18n("Toolbar"),configureToolBarMenu );
menuBar->insertItem( i18n("Filter"),selectFilterMenu );
menuBar->insertItem( i18n("Help"), helpMenu );
//menuBar1->setMaximumWidth( menuBar1->sizeHint().width() );
menuBar1->setMaximumSize( menuBar1->sizeHint( ));
}
connect ( selectFilterMenu, SIGNAL( activated ( int ) ), this, SLOT (selectFilter( int ) ) );
connect ( selectFilterMenu, SIGNAL( aboutToShow() ), this, SLOT (fillFilterMenu() ) );
mWeekBgColor = iconToolBar->backgroundColor();
mWeekPixmap.resize( pixWid , pixHei );
mWeekPixmap.fill( mWeekBgColor );
icon = mWeekPixmap;
mWeekAction = new QAction( i18n("Select week number"),icon, i18n("Select week number"), 0, this );
if ( p-> mShowIconWeekNum )
mWeekAction->addTo( iconToolBar );
mWeekFont = font();
int fontPoint = mWeekFont.pointSize();
QFontMetrics f( mWeekFont );
int fontWid = f.width( "30" );
while ( fontWid > pixWid ) {
--fontPoint;
mWeekFont.setPointSize( fontPoint );
QFontMetrics f( mWeekFont );
fontWid = f.width( "30" );
//qDebug("dec-- ");
}
connect( mWeekAction, SIGNAL( activated() ),
this, SLOT( weekAction() ) );
connect( this, SIGNAL( selectWeek ( int ) ), mView->dateNavigator(), SLOT( selectWeek ( int ) ) );
if ( p->mShowIconFilterview ) {
icon = loadPixmap( pathString + "filter" );
actionFilterMenuTB = new QAction( i18n("Filter selector"), icon, i18n("Filter selector"), 0, this );
connect( actionFilterMenuTB, SIGNAL( activated() ),
this, SLOT( fillFilterMenuTB() ) );
actionFilterMenuTB->addTo( iconToolBar );
selectFilterMenuTB = new QPopupMenu( this );
selectFilterMenuTB->setCheckable( true );
connect ( selectFilterMenuTB, SIGNAL( activated ( int ) ), this, SLOT (selectFilter( int ) ) );
}
//#endif
// ******************
QAction *action;
// QPopupMenu *configureMenu= new QPopupMenu( menuBar );
configureToolBarMenu->setCheckable( true );
configureAgendaMenu->setCheckable( true );
int iii ;
for ( iii = 1;iii<= 10 ;++iii ){
configureAgendaMenu->insertItem(i18n("Size %1").arg(iii), (iii+1)*2 );
}
//configureMenu->insertItem( "AgendaSize",configureAgendaMenu );
connect( configureAgendaMenu, SIGNAL( aboutToShow()),
this, SLOT( showConfigureAgenda( ) ) );
icon = loadPixmap( pathString + "configure" );
action = new QAction( i18n("Configure"),icon, i18n("Configure..."), 0, this );
action->addTo( actionMenu );
connect( action, SIGNAL( activated() ),
mView, SLOT( edit_options() ) );
actionMenu->insertSeparator();
action = new QAction( i18n("Undo Delete"), i18n("Undo Delete..."), 0, this );
action->addTo( actionMenu );
connect( action, SIGNAL( activated() ),
mView, SLOT( undo_delete() ) );
actionMenu->insertSeparator();
icon = loadPixmap( pathString + "newevent" );
configureToolBarMenu->insertItem(i18n("Stretched TB"), 5 );
configureToolBarMenu->insertItem(i18n("Only one toolbar"), 6 );
@@ -1901,512 +1912,525 @@ void MainWindow::keyPressEvent ( QKeyEvent * e )
break;
case Qt::Key_C:
mView->viewManager()->agendaView()->setStartHour( QTime::currentTime ().hour() );
break;
case Qt::Key_P:
mView->showDatePicker( );
break;
case Qt::Key_F:
if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton )
mView->editFilters();
else
mView->toggleFilter();
break;
case Qt::Key_X:
mView->toggleDateNavigatorWidget();
break;
case Qt::Key_Space:
mView->toggleExpand();
break;
case Qt::Key_A:
if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton )
mView->showNextAlarms();
else
mView->toggleAllDaySize();
break;
case Qt::Key_T:
if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton )
mView->newTodo();
else {
mView->goToday();
showSelectedDates = true;
}
break;
case Qt::Key_J:
mView->viewManager()->showJournalView();
break;
case Qt::Key_B:
mView->editIncidenceDescription();;
break;
// case Qt::Key_Return:
case Qt::Key_E:
if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton )
mView->newEvent();
else
mView->editIncidence();
break;
case Qt::Key_Plus:
size = p->mHourSize +2;
if ( size <= 22 )
configureAgenda( size );
break;
case Qt::Key_Minus:
size = p->mHourSize - 2;
if ( size >= 4 )
configureAgenda( size );
break;
default:
e->ignore();
}
if ( pro > 0 ) {
mView->selectFilter( pro-1 );
}
if ( showSelectedDates ) {
;// setCaptionToDates();
}
}
void MainWindow::fillFilterMenuTB()
{
selectFilterMenuTB->clear();
selectFilterMenuTB->insertItem(i18n ( "Edit Filters" ), 0 );
selectFilterMenuTB->insertSeparator();
selectFilterMenuTB->insertItem(i18n ( "No Filter" ), 1 );
selectFilterMenuTB->insertSeparator();
QPtrList<CalFilter> fili = mView->filters();
CalFilter *curfilter = mView->filterView()->selectedFilter();
CalFilter *filter = fili.first();
int iii = 2;
bool checkitem = mView->filterView()->filtersEnabled();
while(filter) {
selectFilterMenuTB->insertItem( filter->name(), iii );
if ( filter == curfilter)
selectFilterMenuTB->setItemChecked( iii, checkitem );
filter = fili.next();
++iii;
}
if ( !checkitem )
selectFilterMenuTB->setItemChecked( 1, true );
int x = 0;
int y = iconToolBar->height();
int dX = 0;
int dY = 0;
if ( iconToolBar->orientation () == Qt:: Horizontal ) {
if ( iconToolBar->y() > height()/2 ) {
dY = selectFilterMenuTB->sizeHint().height()+8;
y = 0;
}
} else {
if ( iconToolBar->x() > width()/2 ) { // right side
x=0;
dX= selectFilterMenuTB->sizeHint().width()+8;
y = 0;
} else {
x= iconToolBar->width();
y = 0;
}
}
//qDebug("dax %d dy %d %d %d ", dX, dY, iconToolBar->x(), iconToolBar->y() );
selectFilterMenuTB->popup(iconToolBar->mapToGlobal(QPoint(x,y)-QPoint( dX,dY)));
}
void MainWindow::fillFilterMenu()
{
selectFilterMenu->clear();
selectFilterMenu->insertItem(i18n ( "Edit Filters" ), 0 );
selectFilterMenu->insertSeparator();
selectFilterMenu->insertItem(i18n ( "No Filter" ), 1 );
selectFilterMenu->insertSeparator();
QPtrList<CalFilter> fili = mView->filters();
CalFilter *curfilter = mView->filterView()->selectedFilter();
CalFilter *filter = fili.first();
int iii = 2;
bool checkitem = mView->filterView()->filtersEnabled();
while(filter) {
selectFilterMenu->insertItem( filter->name(), iii );
if ( filter == curfilter)
selectFilterMenu->setItemChecked( iii, checkitem );
filter = fili.next();
++iii;
}
if ( !checkitem )
selectFilterMenu->setItemChecked( 1, true );
}
void MainWindow::fillFilterMenuPopup()
{
filterPopupMenu->clear();
filterPopupMenu->insertItem(i18n ( "No Filter" ), 0 );
filterPopupMenu->insertSeparator();
QPtrList<CalFilter> fili = mView->filters();
CalFilter *curfilter = mView->filterView()->selectedFilter();
CalFilter *filter = fili.first();
int iii = 1;
bool checkitem = mView->filterView()->filtersEnabled();
while(filter) {
filterPopupMenu->insertItem( filter->name(), iii );
if ( filter == curfilter)
filterPopupMenu->setItemChecked( iii, checkitem );
filter = fili.next();
++iii;
}
if ( !checkitem )
filterPopupMenu->setItemChecked( 0, true );
}
void MainWindow::selectFilter( int fil )
{
if ( fil == 0 ) {
mView->editFilters( );
} else if ( fil == 1 ){
if ( mView->filterView()->filtersEnabled() )
mView->toggleFilerEnabled( );
} else {
if ( !mView->filterView()->filtersEnabled() ) {
mView->filterView()->blockSignals( true );
mView->toggleFilerEnabled( );
mView->filterView()->blockSignals( false );
}
mView->selectFilter( fil-2 );
}
}
void MainWindow::updateFilterToolbar()
{
if ( filterMenubar ) {
if ( !mView->filterView()->filtersEnabled() ) {
filterMenubar->changeItem( 0, i18n("No Filter") );
} else {
CalFilter *curfilter = mView->filterView()->selectedFilter();
if ( curfilter ) {
filterMenubar->changeItem( 0, curfilter->name() );
}
}
}
}
void MainWindow::selectFilterPopup( int fil )
{
selectFilter( fil + 1 );
}
void MainWindow::configureToolBar( int item )
{
configureToolBarMenu->setItemChecked( item, !configureToolBarMenu-> isItemChecked ( item ) );
KOPrefs *p = KOPrefs::instance();
p-> mShowIconStretch= configureToolBarMenu->isItemChecked( 5 );
p-> mShowIconOnetoolbar = configureToolBarMenu->isItemChecked( 6 );
p-> mShowIconFilter = configureToolBarMenu->isItemChecked( 7 );
p-> mShowIconNewEvent= configureToolBarMenu->isItemChecked( 10 );
p->mShowIconNewTodo = configureToolBarMenu->isItemChecked( 20 );
p->mShowIconNavigator = configureToolBarMenu->isItemChecked( 22 );
p->mShowIconAllday = configureToolBarMenu->isItemChecked( 24 );
p->mShowIconFilterview = configureToolBarMenu->isItemChecked( 26 );
p->mShowIconToggleFull = configureToolBarMenu->isItemChecked( 28 );
p-> mShowIconSearch= configureToolBarMenu->isItemChecked( 120 );
p-> mShowIconList= configureToolBarMenu->isItemChecked( 30 );
p-> mShowIconDay1= configureToolBarMenu->isItemChecked( 40 );
p-> mShowIconDay5= configureToolBarMenu->isItemChecked( 50 );
p-> mShowIconDay6= configureToolBarMenu->isItemChecked( 75 );
p-> mShowIconDay7= configureToolBarMenu->isItemChecked( 60 );
p-> mShowIconMonth= configureToolBarMenu->isItemChecked( 70 );
p-> mShowIconTodoview= configureToolBarMenu->isItemChecked( 80 );
p-> mShowIconBackFast= configureToolBarMenu->isItemChecked( 200 );
p-> mShowIconBack = configureToolBarMenu->isItemChecked( 210 );
p-> mShowIconToday= configureToolBarMenu->isItemChecked( 130 );
p-> mShowIconForward= configureToolBarMenu->isItemChecked( 220 );
p-> mShowIconForwardFast= configureToolBarMenu->isItemChecked( 230 );
p-> mShowIconNextDays= configureToolBarMenu->isItemChecked( 100 );
p-> mShowIconNext= configureToolBarMenu->isItemChecked( 110 );
p-> mShowIconJournal= configureToolBarMenu->isItemChecked( 90 );
p-> mShowIconWhatsThis= configureToolBarMenu->isItemChecked( 300 );
p-> mShowIconWeekNum= configureToolBarMenu->isItemChecked( 400 );
// initActions();
}
void MainWindow::setCaption ( const QString & c )
{
QString cap = c;
cap.replace( QRegExp("\n"), " " );
cap = cap.stripWhiteSpace();
if ( cap.isEmpty() )
cap = "KO/Pi";
QWidget::setCaption( cap );
}
void MainWindow::setCaptionToDates()
{
QString selDates;
QDate date = mView->startDate();
if ( ! date.isValid() ) {
setCaption("");
return;
}
selDates = KGlobal::locale()->formatDate( date, true);
if (mView->startDate() < mView->endDate() )
selDates += " - " + KGlobal::locale()->formatDate(mView->endDate(), true);
else {
QString addString;
if ( date == QDateTime::currentDateTime().date() )
addString = i18n("Today");
else if ( date == QDateTime::currentDateTime().date().addDays(1) )
addString = i18n("Tomorrow");
if ( !addString.isEmpty() )
selDates = addString+", "+selDates ;
}
setCaption( i18n("Dates: ") + selDates );
}
void MainWindow::showConfigureAgenda( )
{
int iii;
for ( iii = 1;iii<= 10 ;++iii ){
configureAgendaMenu->setItemChecked( (iii+1)*2, false );
}
configureAgendaMenu->setItemChecked( (KOPrefs::instance()->mHourSize/2)*2, true );
}
void MainWindow::configureAgenda( int item )
{
if ( KOPrefs::instance()->mHourSize == item )
return;
KOPrefs::instance()->mHourSize=item;
mView->viewManager()->agendaView()->updateConfig();
}
void MainWindow::saveCalendar()
{
QString fn = KOPrefs::instance()->mLastSaveFile;
fn = KFileDialog::getSaveFileName( fn, i18n("Save backup filename"), this );
if ( fn == "" )
return;
QFileInfo info;
info.setFile( fn );
QString mes;
bool createbup = true;
if ( info. exists() ) {
mes = i18n("Backup file\nalready exists!\nOld backup file from:\n%1\nOverwrite?\n").arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false )) ;
int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes,
i18n("Overwrite!"), i18n("Cancel"), 0,
0, 1 );
if ( result != 0 ) {
createbup = false;
}
}
if ( createbup ) {
mView->saveCalendar( fn );
mes = i18n("KO/Pi:Saved %1").arg(fn);
KOPrefs::instance()->mLastSaveFile = fn;
setCaption(mes);
}
}
void MainWindow::loadCalendar()
{
QString fn = KOPrefs::instance()->mLastLoadFile;
fn = KFileDialog::getOpenFileName( fn, i18n("Load backup filename"), this );
if ( fn == "" )
return;
QFileInfo info;
info.setFile( fn );
QString mess;
bool loadbup = true;
if ( info. exists() ) {
mess = i18n("Backup file from:\n%1\nLoading backup\nfile will delete\nyour current Data!\n").arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false ));
int result = QMessageBox::warning( this, "KO/Pi: Warning!",
mess,
i18n("Load!"), i18n("Cancel"), 0,
0, 1 );
if ( result != 0 ) {
loadbup = false;
}
} else {
QMessageBox::warning( this, i18n("KO/Pi: Warning!"),
i18n("Backup file\ndoes not exist!\nNothing loaded!"), 0, 0,
0, 1 );
return;
}
if ( loadbup ) {
mView->openCalendar( fn );
KOPrefs::instance()->mLastLoadFile = fn;
mess = i18n("KO/Pi:Loaded %1").arg(fn) ;
setCaption(mess);
}
}
void MainWindow::quickImportIcal()
{
importFile( KOPrefs::instance()->mLastImportFile, false );
}
void MainWindow::importFile( QString fn, bool quick )
{
QFileInfo info;
info.setFile( fn );
QString mess;
bool loadbup = true;
if ( !info. exists() ) {
mess = i18n("Import file \n...%1\ndoes not exist!\nNothing imported!\n").arg(fn.right( 30));
int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),
mess );
return;
}
int result = 0;
if ( !quick ) {
mess = i18n( "Import file \n...%1\nfrom:\n%2\nDuplicated entries\nwill not be imported!\n").arg(fn.right( 25)).arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false ));
result = QMessageBox::warning( this, "KO/Pi: Warning!",
mess,
"Import", "Cancel", 0,
0, 1 );
}
if ( result == 0 ) {
if ( mView->openCalendar( fn, true )) {
KOPrefs::instance()->mLastImportFile = fn;
setCaption(i18n("Imported file successfully"));
} else {
setCaption(i18n("Error importing file"));
}
}
}
void MainWindow::importIcal()
{
QString fn =KOPrefs::instance()->mLastImportFile;
fn =KFileDialog:: getOpenFileName( fn, i18n("Import filename(*.ics/*.vcs)"), this );
if ( fn == "" )
return;
importFile( fn, true );
}
void MainWindow::exportVCalendar()
{
QString fn = KOPrefs::instance()->mLastVcalFile;
fn = KFileDialog::getSaveFileName( fn, i18n("Export vcal filename(*.vcs)"), this );
if ( fn == "" )
return;
QFileInfo info;
info.setFile( fn );
QString mes;
bool createbup = true;
if ( info. exists() ) {
mes = i18n("Save file\nalready exists!\nOld save file from:\n%1\nOverwrite?\n").arg (KGlobal::locale()->formatDateTime(info.lastModified (), true, false ) );
int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes,
i18n("Overwrite!"), i18n("Cancel"), 0,
0, 1 );
if ( result != 0 ) {
createbup = false;
}
}
if ( createbup ) {
if ( mView->exportVCalendar( fn ) ) {
KOPrefs::instance()->mLastVcalFile = fn;
if ( fn.length() > 20 )
mes = i18n("KO/Pi:Exported to ...%1").arg(fn.right(20)) ;
else
mes = i18n("KO/Pi:Exported to %1").arg(fn );
setCaption(mes);
}
}
}
QString MainWindow::sentSyncFile()
{
#ifdef DESKTOP_VERSION
return locateLocal( "tmp", "copysynccal.ics" );
#else
return QString( "/tmp/copysynccal.ics" );
#endif
}
void MainWindow::syncFileRequest()
{
if ( KOPrefs::instance()->mPassiveSyncWithDesktop ) {
mSyncManager->slotSyncMenu( 999 );
}
setCaption(i18n("Saving Data to temp file ..." ));
mView->saveCalendar( sentSyncFile() );
setCaption(i18n("Data saved to temp file!" ));
}
void MainWindow::getFile( bool success )
{
if ( ! success ) {
setCaption( i18n("Error receiving file. Nothing changed!") );
return;
}
mView->openCalendar( sentSyncFile() );
if ( KOPrefs::instance()->mPassiveSyncWithDesktop ) {
mSyncManager->slotSyncMenu( 999 );
}
setCaption( i18n("Pi-Sync successful!") );
}
void MainWindow::printSel( )
{
mView->viewManager()->agendaView()->agenda()->printSelection();
}
void MainWindow::printCal()
{
mView->print();//mCp->showDialog();
}
#include "libkdepim/kdatepicker.h"
#include <kdatetbl.h>
void MainWindow::weekAction()
{
int month;
KPopupFrame* popup = new KPopupFrame(this);
KDateInternalWeekPicker* picker = new KDateInternalWeekPicker(popup);
// -----
picker->resize(picker->sizeHint());
popup->setMainWidget(picker);
picker->setFocus();
connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int)));
int x = 0;
int y = iconToolBar->height();
int dX = 0;
int dY = 0;
if ( iconToolBar->orientation () == Qt:: Horizontal ) {
if ( iconToolBar->y() > height()/2 ) {
dY = picker->sizeHint().height()+8;
y = 0;
}
} else {
if ( iconToolBar->x() > width()/2 ) { // right side
x=0;
dX= picker->sizeHint().width()+8;
y = 0;
} else {
x= iconToolBar->width();
y = 0;
}
}
//qDebug("dax %d dy %d %d %d ", dX, dY, iconToolBar->x(), iconToolBar->y() );
if(popup->exec(iconToolBar->mapToGlobal(QPoint(x,y)-QPoint( dX,dY))))
{
month = picker->getResult();
emit selectWeek ( month );
//qDebug("weekSelected %d ", month);
}
delete popup;
}
void MainWindow::hideEvent ( QHideEvent * )
{
QString message;
QDateTime nextA = mCalendar->nextAlarmEventDateTime();
if ( nextA.isValid() ) {
QString sum = mCalendar->nextSummary();
message = i18n("%1 %2 - %3 (next event/todo with alarm)").arg( KGlobal::locale()->formatTime(nextA.time() , false)).arg(sum ).arg( KGlobal::locale()->formatDate(nextA.date() , false));
setCaption( message );
}
}
+
+void MainWindow::resizeEvent( QResizeEvent* e)
+{
+#ifndef DESKTOP_VERSION
+ if ( !KOPrefs::instance()->mShowIconFilter && !KOPrefs::instance()->mShowIconOnetoolbar ) {
+ if (QApplication::desktop()->width() > QApplication::desktop()->height() )
+ filterToolBar->hide();
+ else
+ filterToolBar->show();
+ }
+#endif
+ QMainWindow::resizeEvent( e);
+}
diff --git a/korganizer/mainwindow.h b/korganizer/mainwindow.h
index 7c16aeb..4d1753f 100644
--- a/korganizer/mainwindow.h
+++ b/korganizer/mainwindow.h
@@ -1,172 +1,173 @@
#ifndef KORGE_MAINWINDOW_H
#define KORGE_MAINWINDOW_H
#include <qmainwindow.h>
#include <qtimer.h>
#include <qdict.h>
#include <qfile.h>
#include <qmenubar.h>
#include <qtextstream.h>
#include <qregexp.h>
#include <libkcal/incidence.h>
#include "simplealarmclient.h"
#include <ksyncmanager.h>
#ifndef DESKTOP_VERSION
#include <qcopchannel_qws.h>
#endif
class QAction;
class CalendarView;
class KSyncProfile;
#ifdef DESKTOP_VERSION
#define QPEToolBar QToolBar
#define QPEMenuBar QMenuBar
#endif
class QPEToolBar;
class QPEMenuBar;
namespace KCal {
class CalendarLocal;
}
class KOMenuBar : public QMenuBar
{
public:
KOMenuBar( QWidget *parent=0 ): QMenuBar (parent ) {;}
QSize sizeHint () const{ qDebug("sizejint ");return QSize ( 40,25 );}
};
using namespace KCal;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow( QWidget *parent = 0, const char *name = 0, QString command = "");
~MainWindow();
bool beamReceiveEnabled();
static QString defaultFileName();
static QString syncFileName();
static QString resourcePath();
public slots:
void setCaption ( const QString & );
void updateWeekNum(const KCal::DateList &);
void updateWeek(QDate);
void updateFilterToolbar();
virtual void showMaximized ();
void configureAgenda( int );
void recieve( const QCString& msg, const QByteArray& data );
protected slots:
void setCaptionToDates();
void weekAction();
void about();
void licence();
void faq();
void usertrans();
void features();
void synchowto();
void kdesynchowto();
void multisynchowto();
void whatsNew();
void keyBindings();
void aboutAutoSaving();;
void aboutKnownBugs();
void processIncidenceSelection( Incidence * );
void importQtopia();
void importBday();
void importOL();
void importIcal();
void importFile( QString, bool );
void quickImportIcal();
void slotModifiedChanged( bool );
void save();
void saveStopTimer();
void configureToolBar( int );
void printSel();
void printCal();
void saveCalendar();
void loadCalendar();
void exportVCalendar();
void fillFilterMenu();
void fillFilterMenuTB();
void selectFilter( int );
void fillFilterMenuPopup();
void selectFilterPopup( int );
void exportToPhone( int );
void toggleBeamReceive();
void disableBR(bool);
signals:
void selectWeek ( int );
private slots:
void showConfigureAgenda();
void getFile( bool );
void syncFileRequest();
protected:
void hideEvent ( QHideEvent * );
QString sentSyncFile();
void displayText( QString, QString);
void enableIncidenceActions( bool );
private:
bool mBRdisabled;
#ifndef DESKTOP_VERSION
QCopChannel* infrared;
#endif
QAction* brAction;
KSyncManager* mSyncManager;
bool mClosed;
void saveOnClose();
bool mFlagKeyPressed;
bool mBlockAtStartup;
QPEToolBar *iconToolBar;
QPEToolBar *viewToolBar;
QPEToolBar *navigatorToolBar;
QPEToolBar *filterToolBar;
QPEMenuBar *filterMenubar;
QPopupMenu * filterPopupMenu;
void initActions();
void setDefaultPreferences();
+ void resizeEvent( QResizeEvent* e);
void keyPressEvent ( QKeyEvent * ) ;
void keyReleaseEvent ( QKeyEvent * ) ;
QPopupMenu *configureToolBarMenu;
QPopupMenu *selectFilterMenu;
QPopupMenu *selectFilterMenuTB;
QPopupMenu *configureAgendaMenu, *syncMenu;
CalendarLocal *mCalendar;
CalendarView *mView;
QAction *mNewSubTodoAction;
QAction *mWeekAction;
QFont mWeekFont;
QPixmap mWeekPixmap;
QColor mWeekBgColor;
QAction *mShowAction;
QAction *mEditAction;
QAction *mDeleteAction;
QAction *mCloneAction;
QAction *mMoveAction;
QAction *mBeamAction;
QAction *mCancelAction;
QAction *mToggleNav;
QAction *mToggleFilter;
QAction *mToggleAllday;
QAction *actionFilterMenuTB;
void closeEvent( QCloseEvent* ce );
SimpleAlarmClient mAlarmClient;
QTimer mSaveTimer;
//bool mBlockSaveFlag;
bool mCalendarModifiedFlag;
QPixmap loadPixmap( QString );
};
#endif