projecttab.cpp 20.9 KB
Newer Older
Pino Toscano's avatar
Pino Toscano committed
1
/* ****************************************************************************
Nick Shaforostoff's avatar
Nick Shaforostoff committed
2
  This file is part of Lokalize
3

4
  Copyright (C) 2007-2014 by Nick Shaforostoff <shafff@ukr.net>
Simon Depiets's avatar
Simon Depiets committed
5
                2018-2019 by Simon Depiets <sdepiets@gmail.com>
6

Nick Shaforostoff's avatar
Nick Shaforostoff committed
7
8
9
10
11
  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) version 3 or any later version
  accepted by the membership of KDE e.V. (or its successor approved
Simon Depiets's avatar
Simon Depiets committed
12
  by the membership of KDE e.V.), which shall act as a proxy
Nick Shaforostoff's avatar
Nick Shaforostoff committed
13
  defined in Section 14 of version 3 of the license.
14
15
16
17
18
19
20

  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
Nick Shaforostoff's avatar
Nick Shaforostoff committed
21
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23
24

**************************************************************************** */

25
#include "projecttab.h"
26
#include "project.h"
27
#include "projectwidget.h"
28
#include "tmscanapi.h"
Nick Shaforostoff's avatar
Nick Shaforostoff committed
29
#include "prefs.h"
30
#include "prefs_lokalize.h"
31
#include "catalog.h"
32
#include "lokalize_debug.h"
33

34
35
#include <KActionCategory>
#include <KActionCollection>
36
37
38
39
#include <KGuiItem>
#include <KLocalizedString>
#include <KMessageBox>
#include <KProcess>
40
#include <KStandardAction>
41
#include <KStandardGuiItem>
42
#include <KXMLGUIFactory>
43

44
45
#include <QLineEdit>
#include <QIcon>
46
47
#include <QContextMenuEvent>
#include <QMenu>
48
49
50
#include <QVBoxLayout>
#include <QShortcut>
#include <QSortFilterProxyModel>
51
#include <QStatusBar>
52
#include <QProgressBar>
Nick Shaforostoff's avatar
Nick Shaforostoff committed
53
54
55
#include <QStackedLayout>
#include <QLabel>
#include <QPushButton>
56
#include <QInputDialog>
57

Nick Shaforostoff's avatar
Nick Shaforostoff committed
58
ProjectTab::ProjectTab(QWidget *parent)
59
    : LokalizeSubwindowBase2(parent)
60
    , m_browser(new ProjectWidget(this))
61
    , m_filterEdit(new QLineEdit(this))
62
    , m_pologyProcessInProgress(false)
63
64
    , m_legacyUnitsCount(-1)
    , m_currentUnitsCount(0)
65
66

{
Simon Depiets's avatar
Simon Depiets committed
67
    setWindowTitle(i18nc("@title:window", "Project Overview")); //setCaption(i18nc("@title:window","Project"),false);
Nick Shaforostoff's avatar
Nick Shaforostoff committed
68
//BEGIN setup welcome widget
Simon Depiets's avatar
Simon Depiets committed
69
70
    QWidget* welcomeWidget = new QWidget(this);
    QVBoxLayout* wl = new QVBoxLayout(welcomeWidget);
Nick Shaforostoff's avatar
Nick Shaforostoff committed
71
    QLabel* about = new QLabel(i18n("<html>" //copied from kaboutkdedialog_p.cpp
Simon Depiets's avatar
Simon Depiets committed
72
73
74
75
76
77
78
79
80
81
82
83
                                    "You do not have to be a software developer to be a member of the "
                                    "KDE team. You can join the national teams that translate "
                                    "program interfaces. You can provide graphics, themes, sounds, and "
                                    "improved documentation. You decide!"
                                    "<br /><br />"
                                    "Visit "
                                    "<a href=\"%1\">%1</a> "
                                    "for information on some projects in which you can participate."
                                    "<br /><br />"
                                    "If you need more information or documentation, then a visit to "
                                    "<a href=\"%2\">%2</a> "
                                    "will provide you with what you need.</html>",
84
85
                                    QLatin1String("https://community.kde.org/Get_Involved"),
                                    QLatin1String("https://techbase.kde.org/")), welcomeWidget);
Nick Shaforostoff's avatar
Nick Shaforostoff committed
86
87
88
89
90
91
    about->setAlignment(Qt::AlignCenter);
    about->setWordWrap(true);
    about->setOpenExternalLinks(true);
    about->setTextInteractionFlags(Qt::TextBrowserInteraction);
    about->setTextFormat(Qt::RichText);

92
    QPushButton* conf = new QPushButton(i18n("&Configure Lokalize"), welcomeWidget);
Simon Depiets's avatar
Simon Depiets committed
93
94
95
96
    QPushButton* openProject = new QPushButton(i18nc("@action:inmenu", "Open project"), welcomeWidget);
    QPushButton* createProject = new QPushButton(i18nc("@action:inmenu", "Translate software"), welcomeWidget);
    QPushButton* createOdfProject = new QPushButton(i18nc("@action:inmenu", "Translate OpenDocument"), welcomeWidget);
    connect(conf, &QPushButton::clicked, SettingsController::instance(), &SettingsController::showSettingsDialog);
97
98
99
    connect(openProject, &QPushButton::clicked, this, QOverload<>::of(&ProjectTab::projectOpenRequested));
    connect(createProject, &QPushButton::clicked, SettingsController::instance(), &SettingsController::projectCreate);
    connect(createOdfProject, &QPushButton::clicked, Project::instance(), &Project::projectOdfCreate);
Simon Depiets's avatar
Simon Depiets committed
100
    QHBoxLayout* wbtnl = new QHBoxLayout();
Nick Shaforostoff's avatar
Nick Shaforostoff committed
101
102
103
    wbtnl->addStretch(1);
    wbtnl->addWidget(conf);
    wbtnl->addWidget(openProject);
104
105
    wbtnl->addWidget(createProject);
    wbtnl->addWidget(createOdfProject);
Nick Shaforostoff's avatar
Nick Shaforostoff committed
106
107
108
109
110
111
112
113
114
115
    wbtnl->addStretch(1);

    wl->addStretch(1);
    wl->addWidget(about);
    wl->addStretch(1);
    wl->addLayout(wbtnl);
    wl->addStretch(1);


//END setup welcome widget
Simon Depiets's avatar
Simon Depiets committed
116
    QWidget* baseWidget = new QWidget(this);
Nick Shaforostoff's avatar
Nick Shaforostoff committed
117
    m_stackedLayout = new QStackedLayout(baseWidget);
Simon Depiets's avatar
Simon Depiets committed
118
    QWidget* w = new QWidget(this);
Nick Shaforostoff's avatar
Nick Shaforostoff committed
119
120
    m_stackedLayout->addWidget(welcomeWidget);
    m_stackedLayout->addWidget(w);
121
    connect(Project::instance(), &Project::loaded, this, &ProjectTab::showRealProjectOverview);
Nick Shaforostoff's avatar
Nick Shaforostoff committed
122
123
    if (Project::instance()->isLoaded()) //for --project cmd option
        showRealProjectOverview();
Nick Shaforostoff's avatar
Nick Shaforostoff committed
124

Simon Depiets's avatar
Simon Depiets committed
125
126
    QVBoxLayout* l = new QVBoxLayout(w);

127

128
129
    m_filterEdit->setClearButtonEnabled(true);
    m_filterEdit->setPlaceholderText(i18n("Quick search..."));
Adrian Chaves's avatar
Adrian Chaves committed
130
    m_filterEdit->setToolTip(i18nc("@info:tooltip", "Activated by Ctrl+L.") + ' ' + i18nc("@info:tooltip", "Accepts regular expressions"));
Simon Depiets's avatar
Simon Depiets committed
131
    connect(m_filterEdit, &QLineEdit::textChanged, this, &ProjectTab::setFilterRegExp, Qt::QueuedConnection);
Simon Depiets's avatar
Simon Depiets committed
132
    new QShortcut(Qt::CTRL + Qt::Key_L, this, SLOT(setFocus()), 0, Qt::WidgetWithChildrenShortcut);
133

134
    l->addWidget(m_filterEdit);
135
    l->addWidget(m_browser);
136
137
138
    connect(m_browser, &ProjectWidget::fileOpenRequested, this, &ProjectTab::fileOpenRequested);
    connect(Project::instance()->model(), &ProjectModel::totalsChanged, this, &ProjectTab::updateStatusBar);
    connect(Project::instance()->model(), &ProjectModel::loadingAboutToStart, this, &ProjectTab::initStatusBarProgress);
139

Nick Shaforostoff's avatar
Nick Shaforostoff committed
140
    setCentralWidget(baseWidget);
141
    QStatusBar* statusBar = static_cast<LokalizeSubwindowBase2*>(parent)->statusBar();
142

143
    m_progressBar = new QProgressBar(0);
144
    m_progressBar->setVisible(false);
145
    statusBar->insertWidget(ID_STATUS_PROGRESS, m_progressBar, 1);
146

Simon Depiets's avatar
Simon Depiets committed
147
    setXMLFile(QStringLiteral("projectmanagerui.rc"), true);
148
    setUpdatedXMLFile();
149
    //QAction* action = KStandardAction::find(Project::instance(),&ProjectTab::showTM,actionCollection());
150

151
#define ADD_ACTION_SHORTCUT_ICON(_name,_text,_shortcut,_icon)\
Nick Shaforostoff's avatar
Nick Shaforostoff committed
152
    action = nav->addAction(QStringLiteral(_name));\
153
    action->setText(_text);\
154
    action->setIcon(QIcon::fromTheme(_icon));\
155
    ac->setDefaultShortcut(action, QKeySequence( _shortcut ));
156

157
    QAction *action;
Simon Depiets's avatar
Simon Depiets committed
158
159
    KActionCollection* ac = actionCollection();
    KActionCategory* nav = new KActionCategory(i18nc("@title actions category", "Navigation"), ac);
160

Simon Depiets's avatar
Simon Depiets committed
161
    ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzyUntr", i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology", "Previous not ready"), Qt::CTRL + Qt::SHIFT + Qt::Key_PageUp, "prevfuzzyuntrans")
162
    connect(action, &QAction::triggered, this, &ProjectTab::gotoPrevFuzzyUntr);
163

Simon Depiets's avatar
Simon Depiets committed
164
    ADD_ACTION_SHORTCUT_ICON("go_next_fuzzyUntr", i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology", "Next not ready"), Qt::CTRL + Qt::SHIFT + Qt::Key_PageDown, "nextfuzzyuntrans")
165
    connect(action, &QAction::triggered, this, &ProjectTab::gotoNextFuzzyUntr);
166

Simon Depiets's avatar
Simon Depiets committed
167
    ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzy", i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology", "Previous non-empty but not ready"), Qt::CTRL + Qt::Key_PageUp, "prevfuzzy")
168
    connect(action, &QAction::triggered, this, &ProjectTab::gotoPrevFuzzy);
169

Simon Depiets's avatar
Simon Depiets committed
170
    ADD_ACTION_SHORTCUT_ICON("go_next_fuzzy", i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology", "Next non-empty but not ready"), Qt::CTRL + Qt::Key_PageDown, "nextfuzzy")
171
    connect(action, &QAction::triggered, this, &ProjectTab::gotoNextFuzzy);
172

Simon Depiets's avatar
Simon Depiets committed
173
    ADD_ACTION_SHORTCUT_ICON("go_prev_untrans", i18nc("@action:inmenu", "Previous untranslated"), Qt::ALT + Qt::Key_PageUp, "prevuntranslated")
174
    connect(action, &QAction::triggered, this, &ProjectTab::gotoPrevUntranslated);
175

Simon Depiets's avatar
Simon Depiets committed
176
    ADD_ACTION_SHORTCUT_ICON("go_next_untrans", i18nc("@action:inmenu", "Next untranslated"), Qt::ALT + Qt::Key_PageDown, "nextuntranslated")
177
    connect(action, &QAction::triggered, this, &ProjectTab::gotoNextUntranslated);
178

Simon Depiets's avatar
Simon Depiets committed
179
    ADD_ACTION_SHORTCUT_ICON("go_prev_templateOnly", i18nc("@action:inmenu", "Previous template only"), Qt::CTRL + Qt::Key_Up, "prevtemplate")
180
    connect(action, &QAction::triggered, this, &ProjectTab::gotoPrevTemplateOnly);
181

Simon Depiets's avatar
Simon Depiets committed
182
    ADD_ACTION_SHORTCUT_ICON("go_next_templateOnly", i18nc("@action:inmenu", "Next template only"), Qt::CTRL + Qt::Key_Down, "nexttemplate")
183
    connect(action, &QAction::triggered, this, &ProjectTab::gotoNextTemplateOnly);
184

Simon Depiets's avatar
Simon Depiets committed
185
    ADD_ACTION_SHORTCUT_ICON("go_prev_transOnly", i18nc("@action:inmenu", "Previous translation only"), Qt::ALT + Qt::Key_Up, "prevpo")
186
    connect(action, &QAction::triggered, this, &ProjectTab::gotoPrevTransOnly);
187

Simon Depiets's avatar
Simon Depiets committed
188
    ADD_ACTION_SHORTCUT_ICON("go_next_transOnly", i18nc("@action:inmenu", "Next translation only"), Qt::ALT + Qt::Key_Down, "nextpo")
189
    connect(action, &QAction::triggered, this, &ProjectTab::gotoNextTransOnly);
190

Simon Depiets's avatar
Simon Depiets committed
191
192
193
    action = nav->addAction(QStringLiteral("toggle_translated_files"));
    action->setText(i18nc("@action:inmenu", "Hide completed items"));
    action->setToolTip(i18nc("@action:inmenu", "Hide fully translated files and folders"));
194
195
    action->setIcon(QIcon::fromTheme("hide_table_row"));
    action->setCheckable(true);
Simon Depiets's avatar
Simon Depiets committed
196
    ac->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::Key_T));
197
198
    connect(action, &QAction::triggered, this, &ProjectTab::toggleTranslatedFiles);

199
    //    ADD_ACTION_SHORTCUT_ICON("edit_find",i18nc("@action:inmenu","Find in files"),Qt::ALT+Qt::Key_Down,"nextpo")
200
    //connect(action, &QAction::triggered, this, &ProjectTab::gotoNextTransOnly);
Simon Depiets's avatar
Simon Depiets committed
201
    action = nav->addAction(KStandardAction::Find, this, SLOT(searchInFiles()));
202

Simon Depiets's avatar
Simon Depiets committed
203
    KActionCategory* proj = new KActionCategory(i18nc("@title actions category", "Project"), ac);
204

205
206
    action = proj->addAction(QStringLiteral("project_open"), this, SIGNAL(projectOpenRequested()));
    action->setText(i18nc("@action:inmenu", "Open project"));
207
    action->setIcon(QIcon::fromTheme("project-open"));
Simon Depiets's avatar
Simon Depiets committed
208
209
210
211

    int i = 6;
    while (--i > ID_STATUS_PROGRESS)
        statusBarItems.insert(i, QString());
212

213
214
}

Nick Shaforostoff's avatar
Nick Shaforostoff committed
215
216
217
218
void ProjectTab::showRealProjectOverview()
{
    m_stackedLayout->setCurrentIndex(1);
}
Simon Depiets's avatar
Simon Depiets committed
219
220
221
222
void ProjectTab::showWelcomeScreen()
{
    m_stackedLayout->setCurrentIndex(0);
}
Nick Shaforostoff's avatar
Nick Shaforostoff committed
223

224
225
226
227
228
void ProjectTab::toggleTranslatedFiles()
{
    m_browser->toggleTranslatedFiles();
}

229
QString ProjectTab::currentFilePath()
230
{
231
    return Project::instance()->path();
232
233
}

234
235
void ProjectTab::setFocus()
{
236
237
    m_filterEdit->setFocus();
    m_filterEdit->selectAll();
238
239
240
241
}

void ProjectTab::setFilterRegExp()
{
Simon Depiets's avatar
Simon Depiets committed
242
243
    QString newPattern = m_filterEdit->text();
    if (m_browser->proxyModel()->filterRegExp().pattern() == newPattern)
244
        return;
245

246
    m_browser->proxyModel()->setFilterRegExp(newPattern);
Simon Depiets's avatar
Simon Depiets committed
247
    if (newPattern.size() > 2)
248
249
        m_browser->expandItems();
}
250

Nick Shaforostoff's avatar
Nick Shaforostoff committed
251
void ProjectTab::contextMenuEvent(QContextMenuEvent *event)
252
{
Simon Depiets's avatar
Simon Depiets committed
253
    QMenu* menu = new QMenu(this);
254
    connect(menu, &QMenu::aboutToHide, menu, &QMenu::deleteLater);
255

256
    if (m_browser->selectedItems().size() > 1 || (m_browser->selectedItems().size() == 1 && !m_browser->currentIsTranslationFile())) {
257
        menu->addAction(i18nc("@action:inmenu", "Open selected files"), this, &ProjectTab::openFile);
258
259
        menu->addSeparator();
    } else if (m_browser->currentIsTranslationFile()) {
260
        menu->addAction(i18nc("@action:inmenu", "Open"), this, &ProjectTab::openFile);
261
        menu->addSeparator();
262
    }
263
264
265
    /*menu.addAction(i18nc("@action:inmenu","Find in files"),this,&ProjectTab::findInFiles);
    menu.addAction(i18nc("@action:inmenu","Replace in files"),this,&ProjectTab::replaceInFiles);
    menu.addAction(i18nc("@action:inmenu","Spellcheck files"),this,&ProjectTab::spellcheckFiles);
266
    menu.addSeparator();
267
    menu->addAction(i18nc("@action:inmenu","Get statistics for subfolders"),m_browser,&ProjectTab::expandItems);
268
    */
269
    menu->addAction(i18nc("@action:inmenu", "Add to translation memory"), this, &ProjectTab::scanFilesToTM);
270

271
    menu->addAction(i18nc("@action:inmenu", "Search in files"), this, &ProjectTab::searchInFiles);
272
    menu->addAction(i18nc("@action:inmenu", "Add a comment"), this, &ProjectTab::addComment);
273
274
275
    if (Settings::self()->pologyEnabled()) {
        menu->addAction(i18nc("@action:inmenu", "Launch Pology on files"), this, &ProjectTab::pologyOnFiles);
    }
276
    if (QDir(Project::instance()->templatesRoot()).exists())
277
        menu->addAction(i18nc("@action:inmenu", "Search in files (including templates)"), this, &ProjectTab::searchInFilesInclTempl);
278
279
280
281
282

//     else if (Project::instance()->model()->hasChildren(/*m_proxyModel->mapToSource(*/(m_browser->currentIndex()))
//             )
//     {
//         menu.addSeparator();
283
//         menu.addAction(i18n("Force Scanning"),this,&ProjectTab::slotForceStats);
Simon Depiets's avatar
Simon Depiets committed
284
//
285
//     }
286
287
    menu->popup(event->globalPos());
}
288

289

290
291
void ProjectTab::scanFilesToTM()
{
Simon Depiets's avatar
Simon Depiets committed
292
    TM::scanRecursive(m_browser->selectedItems(), Project::instance()->projectID());
293
294
}

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
void ProjectTab::addComment()
{
    QStringList files = m_browser->selectedItems();
    int i = files.size();
    QStringList previousCommentsTexts = Project::instance()->commentsTexts();
    QStringList previousCommentsFiles = Project::instance()->commentsFiles();
    QString previousComment(QStringLiteral(""));
    if (i >= 1) {
        //Retrieve previous comment (first one)
        int existingItem = previousCommentsFiles.indexOf(Project::instance()->relativePath(files.at(0)));
        if (existingItem != -1 && previousCommentsTexts.count() > existingItem) {
            previousComment = previousCommentsTexts.at(existingItem);
        }
    }

    bool ok;
    QString newComment = QInputDialog::getText(this, i18n("Project file comment"), i18n("Input a comment for this project file:"), QLineEdit::Normal, previousComment, &ok);
    if (!ok)
        return;

    while (--i >= 0) {
        QString filePath = Project::instance()->relativePath(files.at(i));
        int existingItem = previousCommentsFiles.indexOf(filePath);
        if (existingItem != -1 && previousCommentsTexts.count() > existingItem) {
            previousCommentsTexts[existingItem] = newComment;
        } else {
            previousCommentsTexts << newComment;
            previousCommentsFiles << filePath;
        }
    }
    Project::instance()->setCommentsTexts(previousCommentsTexts);
    Project::instance()->setCommentsFiles(previousCommentsFiles);
    Project::instance()->save();
}

330
331
void ProjectTab::searchInFiles(bool templ)
{
Simon Depiets's avatar
Simon Depiets committed
332
333
334
335
336
    QStringList files = m_browser->selectedItems();
    if (!templ) {
        QString templatesRoot = Project::instance()->templatesRoot();
        int i = files.size();
        while (--i >= 0) {
337
338
339
340
341
342
343
344
            if (files.at(i).startsWith(templatesRoot))
                files.removeAt(i);
        }
    }

    emit searchRequested(files);
}

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
void ProjectTab::pologyOnFiles()
{
    if (!m_pologyProcessInProgress) {
        QStringList files = m_browser->selectedItems();
        QString templatesRoot = Project::instance()->templatesRoot();
        QString filesAsString;
        int i = files.size();
        while (--i >= 0) {
            if (files.at(i).endsWith(QStringLiteral(".po")))
                filesAsString += QStringLiteral("\"") + files.at(i) + QStringLiteral("\" ");
        }

        QString command = Settings::self()->pologyCommandFile().replace(QStringLiteral("%f"), filesAsString);
        m_pologyProcess = new KProcess;
        m_pologyProcess->setOutputChannelMode(KProcess::SeparateChannels);
        qCWarning(LOKALIZE_LOG) << "Launching pology command: " << command;
        connect(m_pologyProcess, QOverload<int, QProcess::ExitStatus>::of(&KProcess::finished),
                this, &ProjectTab::pologyHasFinished);
        m_pologyProcess->setShellCommand(command);
        m_pologyProcessInProgress = true;
        m_pologyProcess->start();
    } else {
        KMessageBox::error(this, i18n("A Pology check is already in progress."), i18n("Pology error"));
    }
}

void ProjectTab::pologyHasFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    const QString pologyError = m_pologyProcess->readAllStandardError();
    if (exitStatus == QProcess::CrashExit) {
        KMessageBox::error(this, i18n("The Pology check has crashed unexpectedly:\n%1", pologyError), i18n("Pology error"));
    } else if (exitCode == 0) {
        KMessageBox::information(this, i18n("The Pology check has succeeded"), i18n("Pology success"));
    } else {
        KMessageBox::error(this, i18n("The Pology check has returned an error:\n%1", pologyError), i18n("Pology error"));
    }
    m_pologyProcess->deleteLater();
    m_pologyProcessInProgress = false;
}

385
386
387
388
389
void ProjectTab::searchInFilesInclTempl()
{
    searchInFiles(true);
}

Simon Depiets's avatar
Simon Depiets committed
390
391
void ProjectTab::openFile()
{
392
393
    QStringList files = m_browser->selectedItems();
    int i = files.size();
394
395
396
397
398
399
400

    if (i > 50) {
        QString caption = i18np("You are about to open %1 file", "You are about to open %1 files", i);
        QString text = i18n("Opening a large number of files at the same time can make Lokalize unresponsive.")
                       + QStringLiteral("\n\n")
                       + i18n("Are you sure you want to open this many files?");
        auto yes = KGuiItem(
Simon Depiets's avatar
Simon Depiets committed
401
402
403
                       i18np("&Open %1 File", "&Open %1 Files", i),
                       QStringLiteral("document-open")
                   );
404
        const int answer = KMessageBox::warningYesNo(
Simon Depiets's avatar
Simon Depiets committed
405
406
                               this, text, caption, yes, KStandardGuiItem::cancel()
                           );
407
408
409
410
411
        if (answer != KMessageBox::Yes) {
            return;
        }
    }

412
413
    while (--i >= 0) {
        if (Catalog::extIsSupported(files.at(i)))  {
414
            if (files.at(i).endsWith(QLatin1String(".pot")))
Laurent Montel's avatar
Laurent Montel committed
415
                emit fileOpenRequested(Project::instance()->model()->potToPo(QUrl::fromLocalFile(files.at(i))).toLocalFile(), true);
416
417
            else
                emit fileOpenRequested(files.at(i), true);
418
419
        }
    }
Simon Depiets's avatar
Simon Depiets committed
420
421
422
423
424
425
426
427
428
429
430
431
432
}
void ProjectTab::findInFiles()
{
    emit searchRequested(m_browser->selectedItems());
}
void ProjectTab::replaceInFiles()
{
    emit replaceRequested(m_browser->selectedItems());
}
void ProjectTab::spellcheckFiles()
{
    emit spellcheckRequested(m_browser->selectedItems());
}
433

Simon Depiets's avatar
Simon Depiets committed
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
void ProjectTab::gotoPrevFuzzyUntr()
{
    m_browser->gotoPrevFuzzyUntr();
}
void ProjectTab::gotoNextFuzzyUntr()
{
    m_browser->gotoNextFuzzyUntr();
}
void ProjectTab::gotoPrevFuzzy()
{
    m_browser->gotoPrevFuzzy();
}
void ProjectTab::gotoNextFuzzy()
{
    m_browser->gotoNextFuzzy();
}
void ProjectTab::gotoPrevUntranslated()
{
    m_browser->gotoPrevUntranslated();
}
void ProjectTab::gotoNextUntranslated()
{
    m_browser->gotoNextUntranslated();
}
void ProjectTab::gotoPrevTemplateOnly()
{
    m_browser->gotoPrevTemplateOnly();
}
void ProjectTab::gotoNextTemplateOnly()
{
    m_browser->gotoNextTemplateOnly();
}
void ProjectTab::gotoPrevTransOnly()
{
    m_browser->gotoPrevTransOnly();
}
void ProjectTab::gotoNextTransOnly()
{
    m_browser->gotoNextTransOnly();
}
474

Simon Depiets's avatar
Simon Depiets committed
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
bool ProjectTab::currentItemIsTranslationFile() const
{
    return m_browser->currentIsTranslationFile();
}
void ProjectTab::setCurrentItem(const QString& url)
{
    m_browser->setCurrentItem(url);
}
QString ProjectTab::currentItem() const
{
    return m_browser->currentItem();
}
QStringList ProjectTab::selectedItems() const
{
    return m_browser->selectedItems();
}
491

492
493
494
void ProjectTab::updateStatusBar(int fuzzy, int translated, int untranslated, bool done)
{
    int total = fuzzy + translated + untranslated;
495
    m_currentUnitsCount = total;
496

497
    if (m_progressBar->value() != total && m_legacyUnitsCount > 0)
498
        m_progressBar->setValue(total);
Simon Depiets's avatar
Simon Depiets committed
499
500
    if (m_progressBar->maximum() < qMax(total, m_legacyUnitsCount))
        m_progressBar->setMaximum(qMax(total, m_legacyUnitsCount));
501
502
503
    m_progressBar->setVisible(!done);
    if (done)
        m_legacyUnitsCount = total;
Simon Depiets's avatar
Simon Depiets committed
504
505

    statusBarItems.insert(ID_STATUS_TOTAL, i18nc("@info:status message entries", "Total: %1", total));
506
507
    reflectNonApprovedCount(fuzzy, total);
    reflectUntranslatedCount(untranslated, total);
508
509
510
511
}

void ProjectTab::initStatusBarProgress()
{
Simon Depiets's avatar
Simon Depiets committed
512
    if (m_legacyUnitsCount > 0) {
513
514
        if (m_progressBar->value() != 0)
            m_progressBar->setValue(0);
515
516
        if (m_progressBar->maximum() != m_legacyUnitsCount)
            m_progressBar->setMaximum(m_legacyUnitsCount);
517
518
519
520
        updateStatusBar();
    }
}

521
void ProjectTab::setLegacyUnitsCount(int to)
522
{
523
524
    m_legacyUnitsCount = to;
    m_currentUnitsCount = to;
525
526
527
    initStatusBarProgress();
}

528
//bool ProjectTab::isShown() const {return isVisible();}
529