PersonsVC.mm 8.04 KB
Newer Older
1
/*
2
 *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.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 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#import "PersonsVC.h"

22 23

//Qt
24 25 26 27
#import <QSortFilterProxyModel>
#import <QtMacExtras/qmacfunctions.h>
#import <QPixmap>

28 29 30 31 32 33
//LRC
#import <person.h>
#import <personmodel.h>
#import <callmodel.h>
#import <contactmethod.h>
#import <categorizedcontactmodel.h>
34
#import <globalinstances.h>
35

36 37 38
#import "backends/AddressBookBackend.h"
#import "QNSTreeController.h"
#import "delegates/ImageManipulationDelegate.h"
39
#import "views/HoverTableRowView.h"
40
#import "views/ContextualTableCellView.h"
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

class ReachablePersonModel : public QSortFilterProxyModel
{
public:
    ReachablePersonModel(QAbstractItemModel* parent) : QSortFilterProxyModel(parent)
    {
        setSourceModel(parent);
    }
    virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
    {
        return sourceModel()->index(source_row,0,source_parent).flags() & Qt::ItemIsEnabled;
    }
};


56
@interface PersonsVC () {
57

58 59 60 61 62
    QNSTreeController *treeController;
    __unsafe_unretained IBOutlet NSOutlineView *personsView;
    QSortFilterProxyModel *contactProxyModel;

}
63 64 65 66

@end

@implementation PersonsVC
67 68 69 70 71 72

// Tags for views
NSInteger const IMAGE_TAG       = 100;
NSInteger const DISPLAYNAME_TAG = 200;
NSInteger const DETAILS_TAG     = 300;
NSInteger const CALL_BUTTON_TAG = 400;
73 74 75 76

-(void) awakeFromNib
{
    NSLog(@"INIT PersonsVC");
77
    contactProxyModel = new ReachablePersonModel(&CategorizedContactModel::instance());
78 79 80 81 82 83 84 85 86 87 88 89 90
    contactProxyModel->setSortRole(static_cast<int>(Qt::DisplayRole));
    contactProxyModel->sort(0,Qt::AscendingOrder);
    treeController = [[QNSTreeController alloc] initWithQModel:contactProxyModel];

    [treeController setAvoidsEmptySelection:NO];
    [treeController setChildrenKeyPath:@"children"];

    [personsView bind:@"content" toObject:treeController withKeyPath:@"arrangedObjects" options:nil];
    [personsView bind:@"sortDescriptors" toObject:treeController withKeyPath:@"sortDescriptors" options:nil];
    [personsView bind:@"selectionIndexPaths" toObject:treeController withKeyPath:@"selectionIndexPaths" options:nil];
    [personsView setTarget:self];
    [personsView setDoubleAction:@selector(callContact:)];

91
    CategorizedContactModel::instance().setUnreachableHidden(YES);
92 93
}

94 95 96 97 98
- (void) dealloc
{
    delete contactProxyModel;
}

99 100 101
- (IBAction)callContact:(id)sender
{
    if([[treeController selectedNodes] count] > 0) {
102 103
        auto item = [treeController selectedNodes][0];
        QModelIndex qIdx = [treeController toQIdx:item];
104
        ContactMethod* m = nil;
105 106 107 108 109 110 111
        if (!qIdx.parent().isValid()) {
            if ([personsView isItemExpanded:item]) {
                [[personsView animator] collapseItem:item];
            } else
                [[personsView animator] expandItem:item];
            return;
        }
112 113 114 115 116
        if(((NSTreeNode*)[treeController selectedNodes][0]).indexPath.length == 2) {
            // Person
            QVariant var = qIdx.data((int)Person::Role::Object);
            if (var.isValid()) {
                Person *c = var.value<Person*>();
117
                if (c->phoneNumbers().size() > 0) {
118 119 120 121 122 123 124 125 126 127 128 129
                    m = c->phoneNumbers().first();
                }
            }
        } else if (((NSTreeNode*)[treeController selectedNodes][0]).indexPath.length == 3) {
            //ContactMethod
            QVariant var = qIdx.data(static_cast<int>(ContactMethod::Role::Object));
            if (var.isValid()) {
                m = var.value<ContactMethod *>();
            }
        }

        if(m){
130
            Call* c = CallModel::instance().dialingCall();
131
            c->setPeerContactMethod(m);
132
            c << Call::Action::ACCEPT;
133
            CallModel::instance().selectCall(c);
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
        }
    }
}

#pragma mark - NSOutlineViewDelegate methods

// -------------------------------------------------------------------------------
//	shouldSelectItem:item
// -------------------------------------------------------------------------------
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item;
{
    QModelIndex qIdx = [treeController toQIdx:((NSTreeNode*)item)];
    if(!qIdx.isValid())
        return NO;

149
    return YES;
150 151 152 153 154 155 156 157 158 159 160 161
}

// -------------------------------------------------------------------------------
//	shouldEditTableColumn:tableColumn:item
//
//	Decide to allow the edit of the given outline view "item".
// -------------------------------------------------------------------------------
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    return NO;
}

162 163 164
/* View Based OutlineView: See the delegate method -tableView:viewForTableColumn:row: in NSTableView.
 */
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
165 166 167
{
    QModelIndex qIdx = [treeController toQIdx:((NSTreeNode*)item)];

168 169 170 171 172 173 174
    NSTableCellView *result;

    if(!qIdx.parent().isValid()) {
        result = [outlineView makeViewWithIdentifier:@"LetterCell" owner:outlineView];
        [result setWantsLayer:YES];
        [result setLayer:[CALayer layer]];
    } else if(((NSTreeNode*)item).indexPath.length == 2) {
175
        result = [outlineView makeViewWithIdentifier:@"PersonCell" owner:outlineView];
176 177 178
        NSImageView* photoView = [result viewWithTag:IMAGE_TAG];
        Person* p = qvariant_cast<Person*>(qIdx.data((int)Person::Role::Object));

Alexandre Lision's avatar
Alexandre Lision committed
179
        QVariant photo = GlobalInstances::pixmapManipulator().contactPhoto(p, QSize(40,40));
180
        [photoView setImage:QtMac::toNSImage(qvariant_cast<QPixmap>(photo))];
181 182
        [((ContextualTableCellView*) result) setContextualsControls:[NSMutableArray arrayWithObject:[result viewWithTag:CALL_BUTTON_TAG]]];

183 184 185 186 187
        NSTextField* details = [result viewWithTag:DETAILS_TAG];
        if (p && p->phoneNumbers().size() > 0)
            [details setStringValue:p->phoneNumbers().first()->uri().toNSString()];
    } else {
        result = [outlineView makeViewWithIdentifier:@"ContactMethodCell" owner:outlineView];
188
    }
189 190 191 192 193 194 195

    NSTextField* displayName = [result viewWithTag:DISPLAYNAME_TAG];
    [displayName setStringValue:qIdx.data(Qt::DisplayRole).toString().toNSString()];

    return result;
}

196 197 198 199 200 201 202 203 204 205 206 207 208 209
/* View Based OutlineView: See the delegate method -tableView:rowViewForRow: in NSTableView.
 */
- (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item
{
    QModelIndex qIdx = [treeController toQIdx:((NSTreeNode*)item)];
    HoverTableRowView* result = [outlineView makeViewWithIdentifier:@"HoverRowView" owner:nil];
    if(!qIdx.parent().isValid()) {
        [result setHighlightable:NO];
    } else
        [result setHighlightable:YES];

    return result;
}

210 211 212 213
- (IBAction)callClickedAtRow:(id)sender {
    NSInteger row = [personsView rowForView:sender];
    [personsView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
    [self callContact:nil];
214 215 216 217 218 219 220 221 222 223 224 225 226
}

// -------------------------------------------------------------------------------
//	outlineViewSelectionDidChange:notification
// -------------------------------------------------------------------------------
- (void)outlineViewSelectionDidChange:(NSNotification *)notification
{

}

- (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item
{
    QModelIndex qIdx = [treeController toQIdx:((NSTreeNode*)item)];
227
    return (((NSTreeNode*)item).indexPath.length == 2) ? 60.0 : 20.0;
228 229 230
}

@end