~carlos-mazieri/ubuntu-filemanager-app/samba-ui-03

« back to all changes in this revision

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

  • Committer: Tarmac
  • Author(s): carlos-mazieri
  • Date: 2015-08-07 18:55:58 UTC
  • mfrom: (430.4.2 samba-actions-06)
  • Revision ID: tarmac-20150807185558-gircmkhyy4lw8hab
Introduced Location on Actions, every Action will keep its "sourceLocation" and "targetLocation".

It will be possible to distinguish if an Action is performed in Local Disk only or if there is a remote Location involved.

Some DirItemInfo objects are created by respective Locations which items belong to.

Approved by Arto Jalkanen, Ubuntu Phone Apps Jenkins Bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
128
128
    //it is not necessary to delete
129
129
    auxAction      = 0;
130
130
    copyFile.clear();
131
 
 
132
 
}
133
 
 
134
 
 
 
131
    sourceLocation = 0;
 
132
    targetLocation = 0;
 
133
 
 
134
}
 
135
 
 
136
/*!
 
137
 * \brief FileSystemAction::Action::toggleLocation()
 
138
 *
 
139
 *  It may be useful if there is a Undo Action to do a inverse Action
 
140
 */
 
141
void FileSystemAction::Action::toggleLocation()
 
142
{
 
143
    Location * tmp   = sourceLocation;
 
144
    sourceLocation   = targetLocation;
 
145
    targetLocation   = tmp;
 
146
}
 
147
 
 
148
/*!
 
149
 * \brief FileSystemAction::Action::matchLocations
 
150
 * \return true if sourceLocation is equal targetLocation
 
151
 */
 
152
bool FileSystemAction::Action::matchLocations() const
 
153
{
 
154
    return sourceLocation == targetLocation;
 
155
}
 
156
 
 
157
bool FileSystemAction::Action::isRemote() const
 
158
{
 
159
    return  sourceLocation->isRemote() || targetLocation->isRemote();
 
160
}
135
161
 
136
162
//===============================================================================================
137
163
FileSystemAction::ActionEntry::ActionEntry(): newName(0)
224
250
 
225
251
//===============================================================================================
226
252
/*!
227
 
 * \brief FileSystemAction::createAction
 
253
 * \brief FileSystemAction::createAction() Creates an Action struture
228
254
 * \param type
229
 
 * \param origBase
 
255
 * \param pathUrl  the source URL (just the first one) to find the location
230
256
 * \return
231
257
 */
232
 
FileSystemAction::Action* FileSystemAction::createAction(ActionType type)
 
258
FileSystemAction::Action* FileSystemAction::createAction(ActionType type, const QString& pathUrl)
233
259
{
234
260
    Action * action = new Action();
235
261
    action->type  = type;
 
262
 
 
263
    //get Locations, normal case for paste/remove
 
264
    action->sourceLocation     =  m_locationsFactory->parse(pathUrl);
 
265
    action->targetLocation     =  m_locationsFactory->currentLocation();
 
266
    switch (type)
 
267
    {
 
268
       case ActionMoveToTrash:
 
269
            action->targetLocation = m_locationsFactory->getTrashLocation();
 
270
            break;
 
271
       case ActionRestoreFromTrash:  // the current location must already be TrashLocation
 
272
            action->sourceLocation =  m_locationsFactory->getTrashLocation();
 
273
            //TODO check the URL from trash
 
274
            action->targetLocation =  m_locationsFactory->getDiskLocation();
 
275
            break;
 
276
       default:
 
277
            break;
 
278
    }
 
279
    if (action->sourceLocation == 0)
 
280
    {
 
281
        action->sourceLocation  = m_locationsFactory->getDiskLocation();
 
282
    }
 
283
    if (action->targetLocation == 0)
 
284
    {
 
285
        action->targetLocation  = m_locationsFactory->getDiskLocation();
 
286
    }
236
287
    return action;
237
288
}
238
289
 
263
314
 
264
315
bool FileSystemAction::populateEntry(Action* action, ActionEntry* entry)
265
316
{
266
 
    DirItemInfo info(entry->itemPaths.source());
267
 
    if (!info.exists())
 
317
    QScopedPointer<DirItemInfo> info(action->sourceLocation->newItemInfo(entry->itemPaths.source()));
 
318
    if (!info->exists())
268
319
    {
269
320
        emit error(QObject::tr("File or Directory does not exist"),
270
 
                   info.absoluteFilePath() + QObject::tr(" does not exist")
 
321
                   info->absoluteFilePath() + QObject::tr(" does not exist")
 
322
                  );
 
323
        return false;
 
324
    }
 
325
    if (info->needsAuthentication())
 
326
    {
 
327
        emit error(QObject::tr("Cannot access File or Directory"),
 
328
                   info->absoluteFilePath() + QObject::tr(" it needs Authentication")
271
329
                  );
272
330
        return false;
273
331
    }
283
341
            break;
284
342
    }
285
343
    //this is the item being handled
286
 
    entry->reversedOrder.append(info);
 
344
    entry->reversedOrder.append(*info);
287
345
    // verify if the destination item already exists and it the destination path is in other file system
288
346
    if (entry->type == ActionCopy ||
289
347
        entry->type == ActionMove
290
348
       )
291
349
    {
292
 
        DirItemInfo destination(entry->itemPaths.target());
293
 
        entry->alreadyExists = destination.exists();
294
 
        //check if it is possible to move items
295
 
        if (entry->type == ActionMove && !moveUsingSameFileSystem(entry->itemPaths) )
 
350
        QScopedPointer<DirItemInfo> destination(action->targetLocation->newItemInfo(entry->itemPaths.target()));
 
351
        entry->alreadyExists = destination->exists();
 
352
        // if destination folder exists check for write permission
 
353
        QScopedPointer<DirItemInfo> parentDestination(action->targetLocation->newItemInfo(entry->itemPaths.targetPath()));
 
354
        if (parentDestination->exists() && !parentDestination->isWritable())
 
355
        {
 
356
            emit error(tr("Cannot copy/move items"),
 
357
                       tr("no write permission on folder ") + destination->absoluteFilePath() );
 
358
            return false;
 
359
 
 
360
        }
 
361
        //check if it is possible to move items,
 
362
        //when there is a remote Location it is necessary copy then remove
 
363
        if ( entry->type == ActionMove &&
 
364
             (action->isRemote() || !moveUsingSameFileSystem(entry->itemPaths))
 
365
           )
296
366
        {
297
367
            entry->type = ActionHardMoveCopy; // first step
298
368
        }
299
369
    }
300
370
    //ActionMove will perform a rename, so no Directory expanding is necessary
301
 
    if (entry->type != ActionMove && info.isDir() && !info.isSymLink())
 
371
    if (entry->type != ActionMove && info->isDir() && !info->isSymLink())
302
372
    {
303
 
        QDirIterator it(info.absoluteFilePath(),
 
373
        QDirIterator it(info->absoluteFilePath(),
304
374
                        QDir::AllEntries | QDir::System |
305
375
                              QDir::NoDotAndDotDot | QDir::Hidden,
306
376
                        QDirIterator::Subdirectories);
501
571
            case ActionCopy: // ActionHardMoveCopy is  lso checked here
502
572
            case ActionMove:
503
573
                {
504
 
                   QScopedPointer <DirItemInfo> item(m_locationsFactory->currentLocation()->newItemInfo(curEntry->itemPaths.target()));
 
574
                   QScopedPointer <DirItemInfo> item(m_curAction->targetLocation->newItemInfo(curEntry->itemPaths.target()));
505
575
                   if (!curEntry->added && !curEntry->alreadyExists)
506
576
                   {
507
577
                       curEntry->added = true;
927
997
#if DEBUG_MESSAGES
928
998
        qDebug() << Q_FUNC_INFO << paths;
929
999
#endif
930
 
    Action       *myAction       = createAction(actionType);
 
1000
    Action       *myAction       = createAction(actionType,paths.at(0));
 
1001
    //in case of move, verify if it can be performed
 
1002
    if (actionType == ActionMove && !canMoveItems(myAction, paths))
 
1003
    {
 
1004
        delete myAction;
 
1005
        return;
 
1006
    }
 
1007
    //populate the action and put the action in the queue
 
1008
    bool usingFullPath = myAction->isRemote() || DirItemInfo(paths.at(0)).isAbsolute();
931
1009
    for (int counter=0; counter < paths.count(); counter++)
932
1010
    {
933
 
        DirItemInfo info(paths.at(counter));
934
 
        if (!info.isAbsolute())
935
 
        {
936
 
            info.setFile(m_path, paths.at(counter));
937
 
        }
938
 
        ActionPaths pairPaths(info.absoluteFilePath());
939
 
        pairPaths.setTargetPathOnly(m_path);
 
1011
        ActionPaths pairPaths;
 
1012
        //avoid creating a DirItemInfo if the Url/Path is already full
 
1013
        //remove Locations may take longer to create DirItemInfo object
 
1014
        if (!usingFullPath)
 
1015
        {          
 
1016
            QScopedPointer <DirItemInfo> info (myAction->sourceLocation->newItemInfo(paths.at(counter)));
 
1017
            if (!info->isAbsolute())
 
1018
            {
 
1019
                info->setFile(m_path, paths.at(counter));
 
1020
            }
 
1021
            pairPaths.setSource(info->absoluteFilePath());
 
1022
        }
 
1023
        else
 
1024
        {   //it is already full path/url
 
1025
            pairPaths.setSource(paths.at(counter));
 
1026
        }
 
1027
        pairPaths.setTargetPathOnly(m_path);        
940
1028
        addEntry(myAction, pairPaths);
941
1029
    }
942
1030
    queueAction(myAction);
1155
1243
            }
1156
1244
            if (m_curAction->copyFile.target->remove())
1157
1245
            {
1158
 
                QScopedPointer<DirItemInfo> item(m_locationsFactory->currentLocation()->newItemInfo(m_curAction->copyFile.targetName));
 
1246
                QScopedPointer<DirItemInfo> item(m_curAction->targetLocation->newItemInfo(m_curAction->copyFile.targetName));
1159
1247
                notifyActionOnItem(*item, ItemRemoved);
1160
1248
            }
1161
1249
        }
1184
1272
            notifyProgress();
1185
1273
            if (m_curAction->copyFile.isEntryItem && m_curAction->copyFile.amountSavedToRefresh <= 0)
1186
1274
            {
1187
 
                QScopedPointer <DirItemInfo> item(m_locationsFactory->currentLocation()->newItemInfo(m_curAction->copyFile.targetName));
 
1275
                QScopedPointer <DirItemInfo> item(m_curAction->targetLocation->newItemInfo(m_curAction->copyFile.targetName));
1188
1276
                m_curAction->copyFile.amountSavedToRefresh = AMOUNT_COPIED_TO_REFRESH_ITEM_INFO;
1189
1277
                notifyActionOnItem(*item, ItemChanged);
1190
1278
            }
1325
1413
    {
1326
1414
        if (m_curAction->auxAction == 0)
1327
1415
        {   // this new action as Remove will remove all dirs
1328
 
            m_curAction->auxAction            = createAction(ActionRemove);
 
1416
            m_curAction->auxAction            = createAction(ActionRemove, tempDir);
1329
1417
            m_curAction->auxAction->isAux     = true;
1330
1418
            m_queuedActions.append(m_curAction->auxAction);
1331
1419
        }
1448
1536
 */
1449
1537
void FileSystemAction::moveToTrash(const ActionPathList &pairPaths)
1450
1538
{
1451
 
    Action *moveAction = createAction(ActionMoveToTrash);
 
1539
    Action *moveAction = createAction(ActionMoveToTrash, pairPaths.at(0).source());
1452
1540
    for (int counter=0; counter < pairPaths.count(); ++counter)
1453
1541
    {
1454
1542
        addEntry(moveAction, pairPaths.at(counter));
1464
1552
 */
1465
1553
void FileSystemAction::restoreFromTrash(const ActionPathList &pairPaths)
1466
1554
{
1467
 
    Action *moveAction = createAction(ActionRestoreFromTrash);
 
1555
    Action *moveAction = createAction(ActionRestoreFromTrash, pairPaths.at(0).source());
1468
1556
    for (int counter=0; counter < pairPaths.count(); ++counter)
1469
1557
    {
1470
1558
        addEntry(moveAction, pairPaths.at(counter));
1519
1607
    }
1520
1608
}
1521
1609
 
 
1610
 
 
1611
bool FileSystemAction::canMoveItems(Action *action, const QStringList& items)
 
1612
{
 
1613
    QScopedPointer<DirItemInfo> item(action->targetLocation->newItemInfo(items.at(0)));
 
1614
    //check if moving items are being moved to the same placce
 
1615
    if (action->matchLocations() &&
 
1616
        action->sourceLocation->info()->absoluteFilePath() ==  item->absolutePath())
 
1617
    {
 
1618
        QString titleError     = tr("Cannot move items");
 
1619
        emit error(titleError,
 
1620
                   tr("origin and destination folders are the same"));
 
1621
        return false;
 
1622
    }
 
1623
    //source items need to be removed, check for write permission
 
1624
    if (!action->sourceLocation->info()->isWritable())
 
1625
    {
 
1626
        QString titleError     = tr("Cannot move items");
 
1627
        QString noWriteError   = tr("no write permission on folder ");
 
1628
        emit error(titleError, noWriteError + action->sourceLocation->info()->absoluteFilePath());
 
1629
        return false;
 
1630
    }
 
1631
    //target permission is checked in populateEntry()
 
1632
    return true;
 
1633
}