summaryrefslogtreecommitdiffstats
path: root/amarok/src/scancontroller.h
blob: 05de237320ff3aa674a155591db29dd325afcfed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/***************************************************************************
 *   Copyright (C) 2003-2005 by The Amarok Developers                      *
 *                                                                         *
 *   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.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.          *
 ***************************************************************************/

#ifndef AMAROK_SCANCONTROLLER_H
#define AMAROK_SCANCONTROLLER_H

#include <tqmutex.h>
#include <tqxml.h>         //baseclass

#include "threadmanager.h" //baseclass

class CollectionDB;
class KProcIO;

/**
 * @class ScanController
 * @short Starts and controls the external amarokcollectionscanner application.
 * @author Mark Kretschmann <markey@web.de>
 *
 * The collection scanner itself is run in an external process, unlike before, where it
 * used to be thread. The advantage is that the scanner cannot crash the Amarok main
 * application any more. If it crashes we can simply restart it.
 *
 * Amarok communicates with the scanner via the ScanController class, which processes
 * XML entities written to stdout by the scanner process. For XML parsing an event
 * driven SAX2 parser is used, which can process the entities as they arrive, without
 * the need for a DOM document structure.
 */
#ifdef Q_MOC_RUN
// MOC_SKIP_BEGIN
class ScanController : public JobBase, public TQXmlDefaultHandler
// MOC_SKIP_END
#else // Q_MOC_RUN
class ScanController : public ThreadManager::DependentJob, public TQXmlDefaultHandler
#endif // Q_MOC_RUN
{
    Q_OBJECT
    TQ_OBJECT

    public:
        static const int RestartEventType = 8891;

        class RestartEvent : public TQCustomEvent {
            public:
                RestartEvent() : TQCustomEvent( RestartEventType ) {}
        };

        static const int PlaylistFoundEventType = 8890;

        class PlaylistFoundEvent : public TQCustomEvent {
            public:
                PlaylistFoundEvent( TQString path )
                    : TQCustomEvent( PlaylistFoundEventType )
                    , m_path( path ) {}
                TQString path() { return m_path; }
            private:
                TQString m_path;
        };

    public:
        ScanController( CollectionDB* parent, bool incremental, const TQStringList& folders = TQStringList() );
        ~ScanController();
        static ScanController* instance();
        
        virtual void completeJob( void );

        bool isIncremental() const { return m_incremental; }
        bool hasChanged() const { return m_hasChanged; }

        void notifyThisBundle( MetaBundle* bundle );
        bool isPaused() { return m_isPaused; }
        bool tablesCreated() { return m_tablesCreated; }

    signals:
        void scannerAcknowledged();
        void scanDone( bool changed );

    public slots:
        bool requestPause();
        bool requestUnpause();
        void requestAcknowledged();
        void slotFileMoved( const TQString &src, const TQString &dest );

    private slots:
        void slotReadReady();

    private:
        void initIncremental();
        virtual bool doJob();
        static void setInstance( ScanController* instance );

        bool startElement( const TQString&, const TQString &localName, const TQString&, const TQXmlAttributes &attrs );
        void customEvent( TQCustomEvent* );

        // Member variables:
        static const uint MAX_RESTARTS = 80;
        static const uint MAX_FAILURE_PERCENTAGE = 5;

        KProcIO* m_scanner;
        TQStringList m_folders;
        TQStringList m_foldersToRemove;
        bool m_incremental;
        bool m_hasChanged;

        TQString m_xmlData;
        TQMutex m_dataMutex;
        TQXmlInputSource* m_source;
        TQXmlSimpleReader* m_reader;

        TQStringList m_crashedFiles;

        // Every file that the collection scanner finds is marked
        // here, as well as the source of all files that the AFT code
        // detects as having been moved.  These are the files that
        // have definitely not been deleted.  The key is the absolute
        // path.
        TQMap<TQString,TQString> m_filesAdded;
        TQMap<TQString,TQString> m_filesDeleted;
        TQMutex             m_fileMapsMutex;

        static ScanController* currController;

        MetaBundle* m_waitingBundle;
        bool m_lastCommandPaused;
        bool m_isPaused;
        bool m_tablesCreated;
        int m_scanCount;
};


#endif // AMAROK_SCANCONTROLLER_H