Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F16571130
kfoldertree.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
kfoldertree.cpp
View Options
/* -*- mode: C++; c-file-style: "gnu" -*-
This file is part of libkdepim.
Copyright (C) 2002 Carsten Burghardt <burghardt@kde.org>
Copyright (C) 2002 Marc Mutz <mutz@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include
"kfoldertree.h"
#include
<KDebug>
#include
<KLocale>
#include
<KIconLoader>
#include
<kio/global.h>
#include
<QApplication>
#include
<QDropEvent>
#include
<QFontMetrics>
#include
<QMouseEvent>
#include
<QPainter>
#include
<QPixmap>
#include
<QStyle>
#include
<Q3Header>
using
namespace
KPIM
;
//-----------------------------------------------------------------------------
KFolderTreeItem
::
KFolderTreeItem
(
KFolderTree
*
parent
,
const
QString
&
label
,
Protocol
protocol
,
Type
type
)
:
K3ListViewItem
(
parent
,
label
),
mProtocol
(
protocol
),
mType
(
type
),
mUnread
(
-1
),
mTotal
(
0
),
mSize
(
0
),
mFolderIsCloseToQuota
(
false
)
{
}
//-----------------------------------------------------------------------------
KFolderTreeItem
::
KFolderTreeItem
(
KFolderTreeItem
*
parent
,
const
QString
&
label
,
Protocol
protocol
,
Type
type
,
int
unread
,
int
total
)
:
K3ListViewItem
(
parent
,
label
),
mProtocol
(
protocol
),
mType
(
type
),
mUnread
(
unread
),
mTotal
(
total
),
mSize
(
0
),
mFolderIsCloseToQuota
(
false
)
{
}
//-----------------------------------------------------------------------------
int
KFolderTreeItem
::
protocolSortingKey
()
const
{
// protocol dependant sorting order:
// local < imap < news < search < other
switch
(
mProtocol
)
{
case
Local
:
return
1
;
case
CachedImap
:
case
Imap
:
return
2
;
case
News
:
return
3
;
case
Search
:
return
4
;
default
:
return
42
;
}
}
//-----------------------------------------------------------------------------
int
KFolderTreeItem
::
typeSortingKey
()
const
{
// type dependant sorting order:
// inbox < outbox < sent-mail < trash < drafts
// < calendar < contacts < notes < tasks
// < normal folders
switch
(
mType
)
{
case
Inbox
:
return
1
;
case
Outbox
:
return
2
;
case
SentMail
:
return
3
;
case
Trash
:
return
4
;
case
Drafts
:
return
5
;
case
Templates
:
return
6
;
case
Calendar
:
return
7
;
case
Contacts
:
return
8
;
case
Notes
:
return
9
;
case
Tasks
:
return
10
;
default
:
return
42
;
}
}
//-----------------------------------------------------------------------------
int
KFolderTreeItem
::
compare
(
Q3ListViewItem
*
i
,
int
col
,
bool
)
const
{
KFolderTreeItem
*
other
=
static_cast
<
KFolderTreeItem
*>
(
i
);
if
(
col
==
0
)
{
// sort by folder
// local root-folder
if
(
depth
()
==
0
&&
mProtocol
==
NONE
)
{
return
-1
;
}
if
(
other
->
depth
()
==
0
&&
other
->
protocol
()
==
NONE
)
{
return
1
;
}
// first compare by protocol
int
thisKey
=
protocolSortingKey
();
int
thatKey
=
other
->
protocolSortingKey
();
if
(
thisKey
<
thatKey
)
{
return
-1
;
}
if
(
thisKey
>
thatKey
)
{
return
1
;
}
// then compare by type
thisKey
=
typeSortingKey
();
thatKey
=
other
->
typeSortingKey
();
if
(
thisKey
<
thatKey
)
{
return
-1
;
}
if
(
thisKey
>
thatKey
)
{
return
1
;
}
// and finally compare by name
return
text
(
0
).
localeAwareCompare
(
other
->
text
(
0
)
);
}
else
{
// sort by unread or total-column
qint64
a
=
0
,
b
=
0
;
if
(
col
==
static_cast
<
KFolderTree
*>
(
listView
()
)
->
unreadIndex
()
)
{
a
=
mUnread
;
b
=
other
->
unreadCount
();
}
else
if
(
col
==
static_cast
<
KFolderTree
*>
(
listView
()
)
->
totalIndex
()
)
{
a
=
mTotal
;
b
=
other
->
totalCount
();
}
else
if
(
col
==
static_cast
<
KFolderTree
*>
(
listView
()
)
->
sizeIndex
()
)
{
a
=
mSize
;
b
=
other
->
folderSize
();
}
if
(
a
==
b
)
{
return
0
;
}
else
{
return
(
a
<
b
?
-1
:
1
);
}
}
}
//-----------------------------------------------------------------------------
void
KFolderTreeItem
::
setUnreadCount
(
int
aUnread
)
{
if
(
aUnread
<
0
)
{
return
;
}
mUnread
=
aUnread
;
QString
unread
;
if
(
mUnread
==
0
)
{
unread
=
"- "
;
}
else
{
unread
.
setNum
(
mUnread
);
unread
+=
' '
;
}
setText
(
static_cast
<
KFolderTree
*>
(
listView
()
)
->
unreadIndex
(),
unread
);
}
//-----------------------------------------------------------------------------
void
KFolderTreeItem
::
setTotalCount
(
int
aTotal
)
{
if
(
aTotal
<
0
)
{
return
;
}
mTotal
=
aTotal
;
QString
total
;
if
(
mTotal
==
0
)
{
total
=
"- "
;
}
else
{
total
.
setNum
(
mTotal
);
total
+=
' '
;
}
setText
(
static_cast
<
KFolderTree
*>
(
listView
()
)
->
totalIndex
(),
total
);
}
//-----------------------------------------------------------------------------
void
KFolderTreeItem
::
setFolderSize
(
qint64
aSize
)
{
if
(
aSize
<
0
)
{
return
;
// we need to update even if nothing changed, kids ...
}
mSize
=
aSize
;
QString
size
;
qint64
recursiveSize
=
0
;
if
(
childCount
()
>
0
&&
!
isOpen
()
)
{
recursiveSize
=
recursiveFolderSize
();
}
if
(
mType
!=
Root
)
{
if
(
mSize
==
0
&&
(
childCount
()
==
0
||
isOpen
()
||
recursiveSize
==
0
)
)
{
size
=
"- "
;
}
else
{
size
=
KIO
::
convertSize
(
mSize
);
}
}
if
(
childCount
()
>
0
&&
!
isOpen
()
&&
recursiveSize
!=
mSize
)
{
if
(
mType
!=
Root
)
{
size
+=
QString
::
fromLatin1
(
" + %1"
).
arg
(
KIO
::
convertSize
(
recursiveSize
-
mSize
)
);
}
else
{
size
=
KIO
::
convertSize
(
recursiveSize
);
}
}
size
+=
' '
;
setText
(
static_cast
<
KFolderTree
*>
(
listView
()
)
->
sizeIndex
(),
size
);
}
//-----------------------------------------------------------------------------
qint64
KFolderTreeItem
::
recursiveFolderSize
()
const
{
qint64
size
=
mSize
;
for
(
Q3ListViewItem
*
item
=
firstChild
();
item
;
item
=
item
->
nextSibling
()
)
{
size
+=
static_cast
<
KFolderTreeItem
*>
(
item
)
->
recursiveFolderSize
();
}
return
size
;
}
//-----------------------------------------------------------------------------
int
KFolderTreeItem
::
countUnreadRecursive
()
{
int
count
=
(
mUnread
>
0
)
?
mUnread
:
0
;
for
(
Q3ListViewItem
*
item
=
firstChild
();
item
;
item
=
item
->
nextSibling
()
)
{
count
+=
static_cast
<
KFolderTreeItem
*>
(
item
)
->
countUnreadRecursive
();
}
return
count
;
}
//-----------------------------------------------------------------------------
void
KFolderTreeItem
::
paintCell
(
QPainter
*
p
,
const
QColorGroup
&
cg
,
int
column
,
int
width
,
int
align
)
{
KFolderTree
*
ft
=
static_cast
<
KFolderTree
*>
(
listView
()
);
const
int
unreadRecursiveCount
=
countUnreadRecursive
();
const
int
unreadCount
=
(
mUnread
>
0
)
?
mUnread
:
0
;
// use a special color for folders which are close to their quota
QColorGroup
mycg
=
cg
;
if
(
(
column
==
0
||
column
==
ft
->
sizeIndex
()
)
&&
folderIsCloseToQuota
()
)
{
mycg
.
setColor
(
QColorGroup
::
Text
,
ft
->
paintInfo
().
colCloseToQuota
);
}
// use a bold-font for the folder- and the unread-columns
if
(
(
column
==
0
||
column
==
ft
->
unreadIndex
()
)
&&
(
unreadCount
>
0
||
(
!
isOpen
()
&&
unreadRecursiveCount
>
0
)
)
)
{
QFont
f
=
p
->
font
();
f
.
setWeight
(
QFont
::
Bold
);
p
->
setFont
(
f
);
}
// most cells can be handled by K3ListView::paintCell, we only need to
// deal with the folder column if the unread column is not shown
/* The below is exceedingly silly, but Ingo insists that the unread
* count that is shown in parenthesis after the folder name must
* be configurable in color. That means that paintCell needs to do
* two painting passes which flickers. Since that flicker is not
* needed when there is the unread column, special case that. */
if
(
/*ft->isUnreadActive() ||*/
column
!=
0
)
{
K3ListViewItem
::
paintCell
(
p
,
mycg
,
column
,
width
,
align
);
}
else
{
Q3ListView
*
lv
=
listView
();
K3ListViewItem
::
paintCell
(
p
,
mycg
,
column
,
width
,
align
);
const
QPixmap
*
icon
=
pixmap
(
column
);
int
marg
=
lv
?
lv
->
itemMargin
()
:
1
;
int
r
=
marg
;
if
(
isSelected
()
)
{
p
->
setPen
(
mycg
.
color
(
QPalette
::
HighlightedText
)
);
}
else
{
p
->
setPen
(
mycg
.
color
(
QPalette
::
Text
)
);
}
if
(
icon
)
{
r
+=
icon
->
width
()
+
marg
;
}
//Remove any text that K3ListViewItem::paintCell() has drawn. We will
//draw that ourselves below.
if
(
isSelected
()
)
{
p
->
fillRect
(
r
,
0
,
width
-
marg
-
r
,
height
(),
mycg
.
brush
(
QPalette
::
Highlight
)
);
}
else
{
p
->
fillRect
(
r
,
0
,
width
-
marg
-
r
,
height
(),
mycg
.
brush
(
QPalette
::
Base
)
);
}
QString
t
=
text
(
column
);
if
(
t
.
isEmpty
()
)
{
return
;
}
// draw the unread-count if the unread-column is not active
QString
unread
;
if
(
!
ft
->
isUnreadActive
()
&&
(
unreadCount
>
0
||
(
!
isOpen
()
&&
unreadRecursiveCount
>
0
)
)
)
{
if
(
isOpen
()
)
{
unread
=
" ("
+
QString
::
number
(
unreadCount
)
+
')'
;
}
else
if
(
unreadRecursiveCount
==
unreadCount
||
mType
==
Root
)
{
unread
=
" ("
+
QString
::
number
(
unreadRecursiveCount
)
+
')'
;
}
else
{
unread
=
" ("
+
QString
::
number
(
unreadCount
)
+
" + "
+
QString
::
number
(
unreadRecursiveCount
-
unreadCount
)
+
')'
;
}
}
// check if the text needs to be squeezed
QFontMetrics
fm
(
p
->
fontMetrics
()
);
int
unreadWidth
=
fm
.
width
(
unread
);
if
(
fm
.
width
(
t
)
+
marg
+
r
+
unreadWidth
>
width
)
{
t
=
squeezeFolderName
(
t
,
fm
,
width
-
marg
-
r
-
unreadWidth
);
}
QRect
br
;
p
->
drawText
(
r
,
0
,
width
-
marg
-
r
,
height
(),
align
|
Qt
::
AlignVCenter
,
t
,
&
br
);
if
(
!
unread
.
isEmpty
()
)
{
if
(
!
isSelected
()
)
{
p
->
setPen
(
ft
->
paintInfo
().
colUnread
);
}
p
->
drawText
(
br
.
right
(),
0
,
width
-
marg
-
br
.
right
(),
height
(),
align
|
Qt
::
AlignVCenter
,
unread
);
}
}
}
QString
KFolderTreeItem
::
squeezeFolderName
(
const
QString
&
text
,
const
QFontMetrics
&
fm
,
uint
width
)
const
{
return
fm
.
elidedText
(
text
,
Qt
::
ElideRight
,
width
);
}
bool
KFolderTreeItem
::
folderIsCloseToQuota
()
const
{
return
mFolderIsCloseToQuota
;
}
void
KFolderTreeItem
::
setFolderIsCloseToQuota
(
bool
v
)
{
if
(
mFolderIsCloseToQuota
!=
v
)
{
mFolderIsCloseToQuota
=
v
;
repaint
();
}
}
//=============================================================================
KFolderTree
::
KFolderTree
(
QWidget
*
parent
,
const
char
*
name
)
:
K3ListView
(
parent
),
mUnreadIndex
(
-1
),
mTotalIndex
(
-1
),
mSizeIndex
(
-1
)
{
setObjectName
(
name
);
// GUI-options
setStyleDependantFrameWidth
();
setAcceptDrops
(
true
);
setDropVisualizer
(
false
);
setAllColumnsShowFocus
(
true
);
setShowSortIndicator
(
true
);
setUpdatesEnabled
(
true
);
setItemsRenameable
(
false
);
setRootIsDecorated
(
true
);
setSelectionModeExt
(
Extended
);
setAlternateBackground
(
QColor
()
);
setShadeSortColumn
(
false
);
setFullWidth
(
true
);
disableAutoSelection
();
setColumnWidth
(
0
,
120
);
//reasonable default size
disconnect
(
header
(),
SIGNAL
(
sizeChange
(
int
,
int
,
int
))
);
connect
(
header
(),
SIGNAL
(
sizeChange
(
int
,
int
,
int
)),
SLOT
(
slotSizeChanged
(
int
,
int
,
int
))
);
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
setStyleDependantFrameWidth
()
{
// set the width of the frame to a reasonable value for the current GUI style
int
frameWidth
;
if
(
QString
(
style
()
->
metaObject
()
->
className
()
)
==
"KeramikStyle"
)
{
frameWidth
=
style
()
->
pixelMetric
(
QStyle
::
PM_DefaultFrameWidth
)
-
1
;
}
else
{
frameWidth
=
style
()
->
pixelMetric
(
QStyle
::
PM_DefaultFrameWidth
);
}
if
(
frameWidth
<
0
)
{
frameWidth
=
0
;
}
if
(
frameWidth
!=
lineWidth
()
)
{
setLineWidth
(
frameWidth
);
}
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
styleChange
(
QStyle
&
oldStyle
)
{
setStyleDependantFrameWidth
();
K3ListView
::
styleChange
(
oldStyle
);
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
drawContentsOffset
(
QPainter
*
p
,
int
ox
,
int
oy
,
int
cx
,
int
cy
,
int
cw
,
int
ch
)
{
// bool oldUpdatesEnabled = updatesEnabled();
// setUpdatesEnabled(false);
K3ListView
::
drawContentsOffset
(
p
,
ox
,
oy
,
cx
,
cy
,
cw
,
ch
);
// WARNING:This will trigger a repaint and thus an infinite loop!
// setUpdatesEnabled(oldUpdatesEnabled);
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
contentsMousePressEvent
(
QMouseEvent
*
e
)
{
setSelectionModeExt
(
Single
);
K3ListView
::
contentsMousePressEvent
(
e
);
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
contentsMouseReleaseEvent
(
QMouseEvent
*
e
)
{
K3ListView
::
contentsMouseReleaseEvent
(
e
);
setSelectionModeExt
(
Extended
);
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
addAcceptableDropMimetype
(
const
QString
&
mimeType
,
bool
outsideOk
)
{
mAcceptableDropMimetypes
.
append
(
mimeType
);
mAcceptOutside
.
append
(
outsideOk
);
}
//-----------------------------------------------------------------------------
bool
KFolderTree
::
acceptDrag
(
QDropEvent
*
event
)
const
{
Q3ListViewItem
*
item
=
itemAt
(
contentsToViewport
(
event
->
pos
()
)
);
for
(
int
i
=
0
;
i
<
mAcceptableDropMimetypes
.
size
();
i
++
)
{
if
(
event
->
provides
(
mAcceptableDropMimetypes
[
i
].
toLatin1
().
constData
()
)
)
{
if
(
item
)
{
KFolderTreeItem
*
ft
=
static_cast
<
KFolderTreeItem
*>
(
item
);
return
ft
->
acceptDrag
(
event
);
}
else
{
return
mAcceptOutside
[
i
];
}
}
}
return
false
;
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
addUnreadColumn
(
const
QString
&
name
,
int
width
)
{
mUnreadIndex
=
addColumn
(
name
,
width
);
setColumnAlignment
(
mUnreadIndex
,
qApp
->
isRightToLeft
()
?
Qt
::
AlignLeft
:
Qt
::
AlignRight
);
header
()
->
adjustHeaderSize
();
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
addTotalColumn
(
const
QString
&
name
,
int
width
)
{
mTotalIndex
=
addColumn
(
name
,
width
);
setColumnAlignment
(
mTotalIndex
,
qApp
->
isRightToLeft
()
?
Qt
::
AlignLeft
:
Qt
::
AlignRight
);
header
()
->
adjustHeaderSize
();
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
removeUnreadColumn
()
{
if
(
!
isUnreadActive
()
)
{
return
;
}
removeColumn
(
mUnreadIndex
);
if
(
isTotalActive
()
&&
mTotalIndex
>
mUnreadIndex
)
{
mTotalIndex
--
;
}
if
(
isSizeActive
()
&&
mSizeIndex
>
mUnreadIndex
)
{
mSizeIndex
--
;
}
mUnreadIndex
=
-1
;
header
()
->
adjustHeaderSize
();
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
removeTotalColumn
()
{
if
(
!
isTotalActive
()
)
{
return
;
}
removeColumn
(
mTotalIndex
);
if
(
isUnreadActive
()
&&
mTotalIndex
<
mUnreadIndex
)
{
mUnreadIndex
--
;
}
if
(
isSizeActive
()
&&
mTotalIndex
<
mSizeIndex
)
{
mSizeIndex
--
;
}
mTotalIndex
=
-1
;
header
()
->
adjustHeaderSize
();
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
addSizeColumn
(
const
QString
&
name
,
int
width
)
{
mSizeIndex
=
addColumn
(
name
,
width
);
setColumnAlignment
(
mSizeIndex
,
(
qApp
->
layoutDirection
()
==
Qt
::
RightToLeft
)
?
Qt
::
AlignLeft
:
Qt
::
AlignRight
);
header
()
->
adjustHeaderSize
();
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
removeSizeColumn
()
{
if
(
!
isSizeActive
()
)
{
return
;
}
removeColumn
(
mSizeIndex
);
if
(
isUnreadActive
()
&&
mSizeIndex
<
mUnreadIndex
)
{
mUnreadIndex
--
;
}
if
(
isTotalActive
()
&&
mSizeIndex
<
mTotalIndex
)
{
mTotalIndex
--
;
}
mSizeIndex
=
-1
;
header
()
->
adjustHeaderSize
();
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
setFullWidth
(
bool
fullWidth
)
{
if
(
fullWidth
)
{
header
()
->
setStretchEnabled
(
true
,
0
);
}
}
//-----------------------------------------------------------------------------
void
KFolderTree
::
slotSizeChanged
(
int
section
,
int
,
int
newSize
)
{
viewport
()
->
repaint
(
header
()
->
sectionPos
(
section
),
0
,
newSize
,
visibleHeight
()
);
}
#include
"kfoldertree.moc"
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Nov 1, 9:58 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10067556
Default Alt Text
kfoldertree.cpp (16 KB)
Attached To
Mode
rKPR kdepim-runtime
Attached
Detach File
Event Timeline
Log In to Comment