summaryrefslogtreecommitdiffstats
path: root/src/app/mainWindow.cpp
blob: 155ece0928a76f06835804a60f5c6f455e212c30 (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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
//Author:    Max Howell <[email protected]>, (C) 2003-4
//Copyright: See COPYING file that comes with this distribution

#include "mainWindow.h"
#include "part/part.h"
#include "historyAction.h"

#include <cstdlib>            //std::exit()
#include <kaccel.h>           //KStdAccel namespace
#include <kaction.h>
#include <kapplication.h>     //setupActions()
#include <kcombobox.h>        //locationbar
#include <kconfig.h>
#include <kdirselectdialog.h> //slotScanDirectory
#include <kedittoolbar.h>     //for editToolbar dialog
#include <kkeydialog.h>
#include <klibloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kshell.h>
#include <kstatusbar.h>
#include <ktoolbar.h>
#include <kurl.h>
#include <kurlcompletion.h>   //locationbar
#include <qobjectlist.h>
#include <qpopupmenu.h>
#include <qtooltip.h>



namespace Filelight {

MainWindow::MainWindow()
        : KParts::MainWindow()
        , m_part( 0 )
{
    KLibFactory *factory = KLibLoader::self()->factory( "libfilelight" );

    if (!factory) {
       KMessageBox::error( this, i18n("KDE could not find the Filelight Part, or the Filelight Part could not be started. Did you make install?") );
       //exit() seems to not exist inside the std namespace for some users!
       using namespace std;
       exit( 1 ); //don't use QApplication::exit() - it causes a crash
    }

    m_part = (Part *)factory->create( this, "part", "KParts::ReadOnlyPart" );

    setCentralWidget( m_part->widget() );
    setStandardToolBarMenuEnabled( true );
    setupActions();
    createGUI( m_part );

    stateChanged( "scan_failed" ); //bah! doesn't affect the parts' actions, should I add them to the actionCollection here?

    QObjectList *buttons = toolBar()->queryList( "KToolBarButton" );
    if (buttons->isEmpty())
        KMessageBox::error( this, i18n("Filelight is not installed properly, consequently its menus and toolbars will appear reduced or even empty") );
    delete buttons;

    connect( m_part, SIGNAL(started( KIO::Job* )), SLOT(scanStarted()) );
    connect( m_part, SIGNAL(completed()), SLOT(scanCompleted()) );
    connect( m_part, SIGNAL(canceled( const QString& )), SLOT(scanFailed()) );

    //TODO test these
    connect( m_part, SIGNAL(canceled( const QString& )), m_histories, SLOT(stop()) );
    connect( BrowserExtension::childObject( m_part ), SIGNAL(openURLNotify()), SLOT(urlAboutToChange()) );

    KConfig* const config = KGlobal::config();
    config->setGroup( "general" );
    m_combo->setHistoryItems( config->readPathListEntry( "comboHistory" ) );
    applyMainWindowSettings( config, "window" );
}

inline void
MainWindow::setupActions() //singleton function
{
    KActionCollection *const ac = actionCollection();

    m_combo = new KHistoryCombo( this, "history_combo" );
    m_combo->setCompletionObject( new KURLCompletion( KURLCompletion::DirCompletion ) );
    m_combo->setAutoDeleteCompletionObject( true );
    m_combo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
    m_combo->setDuplicatesEnabled( false );

    KStdAction::open( this, SLOT(slotScanDirectory()), ac, "scan_directory" );
    KStdAction::quit( this, SLOT(close()), ac );
    KStdAction::up( this, SLOT(slotUp()), ac );
    KStdAction::configureToolbars(this, SLOT(configToolbars()), ac);
    KStdAction::keyBindings(this, SLOT(configKeys()), ac);

    new KAction( i18n( "Scan &Home Directory" ), "folder_home", CTRL+Key_Home, this, SLOT(slotScanHomeDirectory()), ac, "scan_home" );
    new KAction( i18n( "Scan &Root Directory" ), "folder_red", 0, this, SLOT(slotScanRootDirectory()), ac, "scan_root" );
    new KAction( i18n( "Rescan" ), "reload", KStdAccel::reload(), m_part, SLOT(rescan()), ac, "scan_rescan" );
    new KAction( i18n( "Stop" ), "stop", Qt::Key_Escape, this, SLOT(slotAbortScan()), ac, "scan_stop" );
    new KAction( i18n( "Clear Location Bar" ), KApplication::reverseLayout() ? "clear_left" : "locationbar_erase", 0, m_combo, SLOT(clearEdit()), ac, "clear_location" );
    new KAction( i18n( "Go" ), "key_enter", 0, m_combo, SIGNAL(returnPressed()), ac, "go" );

    KWidgetAction *combo = new KWidgetAction( m_combo, i18n( "Location Bar" ), 0, 0, 0, ac, "location_bar" );
    m_recentScans = new KRecentFilesAction( i18n( "&Recent Scans" ), 0, ac, "scan_recent", 8 );
    m_histories = new HistoryCollection( ac, this, "history_collection" );

    ac->action( "scan_directory" )->setText( i18n( "&Scan Directory..." ) );
    m_recentScans->loadEntries( KGlobal::config() );
    combo->setAutoSized( true ); //FIXME what does this do?

    connect( m_recentScans, SIGNAL(urlSelected( const KURL& )), SLOT(slotScanUrl( const KURL& )) );
    connect( m_combo, SIGNAL(returnPressed()), SLOT(slotComboScan()) );
    connect( m_histories, SIGNAL(activated( const KURL& )), SLOT(slotScanUrl( const KURL& )) );
}

bool
MainWindow::queryExit()
{
    if( !m_part ) //apparently std::exit() still calls this function, and abort() causes a crash..
       return true;

    KConfig* const config = KGlobal::config();

    saveMainWindowSettings( config, "window" );
    m_recentScans->saveEntries( config );
    config->setGroup( "general" );
    config->writePathEntry( "comboHistory", m_combo->historyItems() );
    config->sync();

    return true;
}

inline void
MainWindow::configToolbars() //slot
{
    KEditToolbar dialog( factory(), this );
    dialog.showButtonApply( false );

    if( dialog.exec() )
    {
        createGUI( m_part );
        applyMainWindowSettings( kapp->config(), "window" );
    }
}

inline void
MainWindow::configKeys() //slot
{
    KKeyDialog::configure( actionCollection(), this );
}

inline void
MainWindow::slotScanDirectory()
{
    slotScanUrl( KDirSelectDialog::selectDirectory( m_part->url().path(), false, this ) );
}

inline void MainWindow::slotScanHomeDirectory() { slotScanPath( getenv( "HOME" ) ); }
inline void MainWindow::slotScanRootDirectory() { slotScanPath( "/" ); }
inline void MainWindow::slotUp()                { slotScanUrl( m_part->url().upURL() ); }

inline void
MainWindow::slotComboScan()
{
   const QString path = KShell::tildeExpand(m_combo->lineEdit()->text());
   if (slotScanPath( path ))
      m_combo->addToHistory( path );
}

inline bool
MainWindow::slotScanPath( const QString &path )
{
   return slotScanUrl( KURL::fromPathOrURL( path ) );
}

bool
MainWindow::slotScanUrl( const KURL &url )
{
   const KURL oldUrl = m_part->url();
   const bool b = m_part->openURL( url );

   if (b) {
      m_histories->push( oldUrl );
      action( "go_back" )->KAction::setEnabled( false ); } //FIXME

   return b;
}

inline void
MainWindow::slotAbortScan()
{
    if( m_part->closeURL() ) action( "scan_stop" )->setEnabled( false );
}

inline void
MainWindow::scanStarted()
{
    stateChanged( "scan_started" );
    m_combo->clearFocus();
}

inline void
MainWindow::scanFailed()
{
    stateChanged( "scan_failed" );
    setActionMenuTextOnly( action( "go_up" ), QString::null );
    m_combo->lineEdit()->clear();
}

void
MainWindow::scanCompleted()
{
    KAction *goUp  = action( "go_up" );
    const KURL url = m_part->url();

    stateChanged( "scan_complete" );

    m_combo->lineEdit()->setText( m_part->prettyURL() );

    if ( url.path( 1 ) == "/") {
        goUp->setEnabled( false );
        setActionMenuTextOnly( goUp, QString() );
    }
    else
        setActionMenuTextOnly( goUp, url.upURL().path( 1 ) );

    m_recentScans->addURL( url ); //FIXME doesn't set the tick
}

inline void
MainWindow::urlAboutToChange()
{
   //called when part's URL is about to change internally
   //the part will then create the Map and emit completed()

   m_histories->push( m_part->url() );
}


/**********************************************
  SESSION MANAGEMENT
 **********************************************/

void
MainWindow::saveProperties( KConfig *config ) //virtual
{
   m_histories->save( config );
   config->writeEntry( "currentMap", m_part->url().path() );
}

void
MainWindow::readProperties( KConfig *config ) //virtual
{
   m_histories->restore( config );
   slotScanPath( config->readEntry( "currentMap", QString::null ) );
}

} //namespace Filelight



/// declared in historyAction.h

void setActionMenuTextOnly( KAction *a, QString const &suffix )
{
    QString const menu_text = suffix.isEmpty()
            ? a->text()
            : i18n( "&Up: /home/mxcl", "%1: %2" ).arg( a->text(), suffix );

    for (int i = 0; i < a->containerCount(); ++i) {
        QWidget *w = a->container( i );
        int const id = a->itemId( i );

        if (w->inherits( "QPopupMenu" ))
            static_cast<QPopupMenu*>(w)->changeItem( id, menu_text );

        else if (w->inherits( "KToolBar" )) {
            QWidget *button = static_cast<KToolBar*>(w)->getWidget( id );
            if (button->inherits( "KToolBarButton" ))
                QToolTip::add( button, suffix );
        }
    }
}

#include "mainWindow.moc"