~ubuntu-filemanager-dev/ubuntu-filemanager-app/trunk

« back to all changes in this revision

Viewing changes to src/plugin/folderlistmodel/dirselection.cpp

  • Committer: Bileto Bot
  • Date: 2017-04-04 17:06:41 UTC
  • mfrom: (588.1.19 fix-desktop-file)
  • Revision ID: ci-train-bot@canonical.com-20170404170641-1p15lmx8wodlx2ut
* Rename binary file to ubuntu-filemanager-app
* Join plugin packages into the main package 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 *
 
3
 * Copyright 2014 Canonical Ltd.
 
4
 * Copyright 2014 Carlos J Mazieri <carlos.mazieri@gmail.com>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU Lesser General Public License as published by
 
8
 * the Free Software Foundation; version 3.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public License
 
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 *
 
18
 * File: dirselection.cpp
 
19
 * Date: 29/01/2014
 
20
 */
 
21
 
 
22
#include "dirselection.h"
 
23
#include "diritemabstractlistmodel.h"
 
24
#include <QTimer>
 
25
#include <QDebug>
 
26
 
 
27
 
 
28
#define  VALID_INDEX(index)   (index >= 0 && index < m_model->rowCount())
 
29
 
 
30
DirSelection::DirSelection(QObject *parent) :  QObject(parent)
 
31
{
 
32
}
 
33
 
 
34
DirSelection::DirSelection(DirItemAbstractListModel *parent, DirItemInfoList *listItems) :
 
35
    QObject(parent)
 
36
   ,m_selectedCounter(0)
 
37
   ,m_model(parent)
 
38
   ,m_listItems(listItems)
 
39
   ,m_mode(Single)  
 
40
   ,m_lastSelectedItem(-1)
 
41
{
 
42
}
 
43
 
 
44
 
 
45
 
 
46
QStringList DirSelection::selectedAbsFilePaths() const
 
47
{
 
48
    QStringList ret;
 
49
    int counter = m_model->rowCount();
 
50
    for(int index = 0 ; index < counter; ++index)
 
51
    {
 
52
        if (m_listItems->at(index).isSelected())
 
53
        {
 
54
            ret.append(m_listItems->at(index).absoluteFilePath());
 
55
        }
 
56
    }
 
57
    return ret;
 
58
}
 
59
 
 
60
QStringList DirSelection::selectedNames() const
 
61
{
 
62
    QStringList ret;
 
63
    int counter = m_model->rowCount();
 
64
    for(int index = 0 ; index < counter; ++index)
 
65
    {
 
66
        if (m_listItems->at(index).isSelected())
 
67
        {
 
68
            ret.append(m_listItems->at(index).fileName());
 
69
        }
 
70
    }
 
71
    return ret;
 
72
}
 
73
 
 
74
 
 
75
 
 
76
QList<int>  DirSelection::selectedIndexes()    const
 
77
{
 
78
    QList<int> ret;
 
79
    int counter = m_model->rowCount();
 
80
    for(int index = 0 ; index < counter; ++index)
 
81
    {
 
82
        if (m_listItems->at(index).isSelected())
 
83
        {
 
84
            ret.append(index);
 
85
        }
 
86
    }
 
87
    return ret;
 
88
}
 
89
 
 
90
 
 
91
void DirSelection::clear()
 
92
{   
 
93
    if (priv_clear())
 
94
    {
 
95
        notifyChanges();
 
96
    }
 
97
}
 
98
 
 
99
 
 
100
bool DirSelection::priv_clear()
 
101
{
 
102
    bool notify = m_selectedCounter != 0;
 
103
    if (notify)
 
104
    {
 
105
        int counter = m_model->rowCount();
 
106
        DirItemInfo *data =  m_listItems->data();
 
107
        while (m_selectedCounter > 0  && counter-- )
 
108
        {
 
109
            if ( data[counter].setSelection(false) )
 
110
            {
 
111
                --m_selectedCounter;
 
112
                m_model->notifyItemChanged(counter);              
 
113
            }
 
114
        }
 
115
    }
 
116
    //force it to zero, works when cleaning the buffer first
 
117
    m_selectedCounter  = 0;
 
118
    m_lastSelectedItem = -1;
 
119
    return notify;
 
120
}
 
121
 
 
122
 
 
123
void DirSelection::selectAll()
 
124
{
 
125
    int counter = m_model->rowCount();
 
126
    bool notify = m_selectedCounter != counter;
 
127
    if (notify)
 
128
    {
 
129
        DirItemInfo *data =  m_listItems->data();
 
130
        while ( counter-- )
 
131
        {
 
132
            if ( data[counter].setSelection(true) )
 
133
            {
 
134
                ++m_selectedCounter;
 
135
                m_model->notifyItemChanged(counter);              
 
136
            }
 
137
        }
 
138
        notifyChanges();
 
139
    }
 
140
}
 
141
 
 
142
 
 
143
int DirSelection::counter() const
 
144
{
 
145
    return m_selectedCounter;
 
146
}
 
147
 
 
148
 
 
149
DirSelection::Mode DirSelection::mode() const
 
150
{
 
151
    return m_mode;
 
152
}
 
153
 
 
154
 
 
155
void DirSelection::itemGoingToBeRemoved(const DirItemInfo &item)
 
156
{
 
157
    if (m_selectedCounter > 0 && item.isSelected())
 
158
    {      
 
159
        --m_selectedCounter;
 
160
        notifyChanges();
 
161
    }
 
162
    // item is going to be removed, no QAbstractItemModel::dataChanged() signal is necessary to refresh views
 
163
}
 
164
 
 
165
 
 
166
void DirSelection::setIndex(int index, bool selected)
 
167
{
 
168
     if (VALID_INDEX(index))
 
169
     {
 
170
         int old_selectedCounter = m_selectedCounter;
 
171
         if (selected && m_mode == Single && m_selectedCounter > 0)
 
172
         {
 
173
             priv_clear();
 
174
         }       
 
175
         if (    priv_setIndex(index, selected)
 
176
              || old_selectedCounter != m_selectedCounter
 
177
            )
 
178
         {
 
179
             notifyChanges();
 
180
         }
 
181
     }
 
182
}
 
183
 
 
184
 
 
185
void DirSelection::toggleIndex(int index)
 
186
{
 
187
    if (VALID_INDEX(index))
 
188
    {
 
189
        setIndex(index, !m_listItems->at(index).isSelected());
 
190
    }
 
191
}
 
192
 
 
193
 
 
194
void DirSelection::setMode(Mode m)
 
195
{
 
196
    if (m != m_mode)
 
197
    {
 
198
        m_mode = m;
 
199
        emit modeChanged(m_mode);
 
200
    }
 
201
}
 
202
 
 
203
 
 
204
void DirSelection::notifyChanges()
 
205
{
 
206
    emit selectionChanged(m_selectedCounter);    
 
207
}
 
208
 
 
209
 
 
210
/*!
 
211
 * \brief DirSelection::itemGoingToBeReplaced() it is supposed to control selection writable and readabble states
 
212
 *
 
213
 *     So far it does nothing
 
214
 *
 
215
 * \param oldItemInfo
 
216
 * \param newItemInfo
 
217
 */
 
218
void DirSelection::itemGoingToBeReplaced(const DirItemInfo &oldItemInfo,
 
219
                                         const DirItemInfo &newItemInfo)
 
220
{
 
221
    if (oldItemInfo.isSelected())
 
222
    {
 
223
       // we may add selection writable state in the future
 
224
        Q_UNUSED(newItemInfo);
 
225
    }   
 
226
}
 
227
 
 
228
 
 
229
void DirSelection::selectRange(int indexClicked)
 
230
{
 
231
    bool changed = false;
 
232
    if (   VALID_INDEX(indexClicked)
 
233
        && m_selectedCounter > 0
 
234
        && indexClicked != m_lastSelectedItem
 
235
        && VALID_INDEX(m_lastSelectedItem)
 
236
        && !m_listItems->at(indexClicked).isSelected()
 
237
       )
 
238
    {
 
239
        //go from indexClicked to  m_lastSelectedItem
 
240
        int  increment = indexClicked > m_lastSelectedItem?  -1 : 1;
 
241
        int  nextItem  = indexClicked;
 
242
        int  saved_lastSelectedItem = m_lastSelectedItem;
 
243
        while (priv_setIndex(nextItem, true) && nextItem != saved_lastSelectedItem)
 
244
        {
 
245
            nextItem  += increment;
 
246
            changed    = true;
 
247
        }
 
248
    }
 
249
    if (changed)
 
250
    {
 
251
        notifyChanges();
 
252
    }
 
253
}
 
254
 
 
255
 
 
256
bool DirSelection::priv_setIndex(int index, bool selected)
 
257
{
 
258
    DirItemInfo *data  = m_listItems->data();
 
259
    bool changed = false;
 
260
    if ((changed = data[index].setSelection(selected)))
 
261
    {
 
262
        m_model->notifyItemChanged(index);
 
263
        if (selected)
 
264
        {
 
265
            ++m_selectedCounter;         
 
266
            m_lastSelectedItem = index;
 
267
        }
 
268
        else
 
269
        {
 
270
            --m_selectedCounter;          
 
271
        }
 
272
    }
 
273
    return changed;
 
274
}
 
275
 
 
276
 
 
277
void DirSelection::select(int index, bool range, bool multiSelection )
 
278
{
 
279
    if (range && VALID_INDEX(m_lastSelectedItem))
 
280
    {
 
281
        selectRange(index);
 
282
    }
 
283
    else
 
284
    {
 
285
        if (multiSelection || m_mode == Multi)
 
286
        {
 
287
            Mode saveMode = m_mode;
 
288
            //set Multi selection do not  call clear()
 
289
            m_mode = Multi;
 
290
            toggleIndex(index);
 
291
            m_mode = saveMode;
 
292
        }
 
293
        else
 
294
        {
 
295
            setIndex(index, true);
 
296
        }
 
297
    }
 
298
}
 
299
 
 
300
 
 
301
void DirSelection::setMultiSelection(bool enable)
 
302
{
 
303
    Mode m = enable ? Multi : Single;
 
304
    setMode(m);
 
305
}