diff --git a/src/kebsearchline.cpp b/src/kebsearchline.cpp index 5e9b952f5..c52cfa6c4 100644 --- a/src/kebsearchline.cpp +++ b/src/kebsearchline.cpp @@ -1,693 +1,693 @@ /* This file is part of the KDE project Copyright (C) 2005 Daniel Teske This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or at your option version 3 as published by the Free Software Foundation. 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kebsearchline.h" #include #include #include #include #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////// // public methods //////////////////////////////////////////////////////////////////////////////// class KViewSearchLine::KViewSearchLinePrivate { public: KViewSearchLinePrivate() : listView(nullptr), treeView(nullptr), caseSensitive(false), activeSearch(false), keepParentsVisible(true), queuedSearches(0) {} QListView * listView; QTreeView * treeView; bool caseSensitive; bool activeSearch; bool keepParentsVisible; QString search; int queuedSearches; QLinkedList searchColumns; }; KViewSearchLine::KViewSearchLine(QWidget *parent, QAbstractItemView *v) : KLineEdit(parent) { d = new KViewSearchLinePrivate; setClearButtonShown(true); d->treeView = dynamic_cast(v); d->listView = dynamic_cast(v); connect(this, &KViewSearchLine::textChanged, this, &KViewSearchLine::queueSearch); if(view()) { connect(view(), &QObject::destroyed, this, &KViewSearchLine::listViewDeleted); connect(model(), &QAbstractItemModel::dataChanged, this, &KViewSearchLine::slotDataChanged); connect(model(), &QAbstractItemModel::rowsInserted, this, &KViewSearchLine::slotRowsInserted); connect(model(), &QAbstractItemModel::rowsRemoved, this, &KViewSearchLine::slotRowsRemoved); connect(model(), &QAbstractItemModel::columnsInserted, this, &KViewSearchLine::slotColumnsInserted); connect(model(), &QAbstractItemModel::columnsRemoved, this, &KViewSearchLine::slotColumnsRemoved); connect(model(), &QAbstractItemModel::modelReset, this, &KViewSearchLine::slotModelReset); } else setEnabled(false); } KViewSearchLine::KViewSearchLine(QWidget *parent) : KLineEdit(parent) { d = new KViewSearchLinePrivate; setClearButtonShown(true); d->treeView = nullptr; d->listView = nullptr; connect(this, &KViewSearchLine::textChanged, this, &KViewSearchLine::queueSearch); setEnabled(false); } KViewSearchLine::~KViewSearchLine() { delete d; } QAbstractItemView * KViewSearchLine::view() const { if(d->treeView) return d->treeView; else return d->listView; } bool KViewSearchLine::caseSensitive() const { return d->caseSensitive; } bool KViewSearchLine::keepParentsVisible() const { return d->keepParentsVisible; } //////////////////////////////////////////////////////////////////////////////// // public slots //////////////////////////////////////////////////////////////////////////////// void KViewSearchLine::updateSearch(const QString &s) { if(!view()) return; d->search = s.isNull() ? text() : s; // If there's a selected item that is visible, make sure that it's visible // when the search changes too (assuming that it still matches). //FIXME reimplement if(d->keepParentsVisible) checkItemParentsVisible(model()->index(0,0, QModelIndex())); else checkItemParentsNotVisible(); } void KViewSearchLine::setCaseSensitive(bool cs) { d->caseSensitive = cs; } void KViewSearchLine::setKeepParentsVisible(bool v) { d->keepParentsVisible = v; } void KViewSearchLine::setSearchColumns(const QLinkedList &columns) { d->searchColumns = columns; } void KViewSearchLine::setView(QAbstractItemView *v) { if(view()) { disconnect(view(), &QObject::destroyed, this, &KViewSearchLine::listViewDeleted); disconnect(model(), &QAbstractItemModel::dataChanged, this, &KViewSearchLine::slotDataChanged); disconnect(model(), &QAbstractItemModel::rowsInserted, this, &KViewSearchLine::slotRowsInserted); disconnect(model(), &QAbstractItemModel::rowsRemoved, this, &KViewSearchLine::slotRowsRemoved); disconnect(model(), &QAbstractItemModel::columnsInserted, this, &KViewSearchLine::slotColumnsInserted); disconnect(model(), &QAbstractItemModel::columnsRemoved, this, &KViewSearchLine::slotColumnsRemoved); disconnect(model(), &QAbstractItemModel::modelReset, this, &KViewSearchLine::slotModelReset); } d->treeView = dynamic_cast(v); d->listView = dynamic_cast(v); if(view()) { connect(view(), &QObject::destroyed, this, &KViewSearchLine::listViewDeleted); connect(model(), &QAbstractItemModel::dataChanged, this, &KViewSearchLine::slotDataChanged); connect(model(), &QAbstractItemModel::rowsInserted, this, &KViewSearchLine::slotRowsInserted); connect(model(), &QAbstractItemModel::rowsRemoved, this, &KViewSearchLine::slotRowsRemoved); connect(model(), &QAbstractItemModel::columnsInserted, this, &KViewSearchLine::slotColumnsInserted); connect(model(), &QAbstractItemModel::columnsRemoved, this, &KViewSearchLine::slotColumnsRemoved); connect(model(), &QAbstractItemModel::modelReset, this, &KViewSearchLine::slotModelReset); } setEnabled(bool(view())); } //////////////////////////////////////////////////////////////////////////////// // protected members //////////////////////////////////////////////////////////////////////////////// bool KViewSearchLine::itemMatches(const QModelIndex & item, const QString &s) const { if(s.isEmpty()) return true; // If the search column list is populated, search just the columns // specified. If it is empty default to searching all of the columns. if(d->treeView) { int columnCount = d->treeView->header()->count(); int row = item.row(); QModelIndex parent = item.parent(); if(!d->searchColumns.isEmpty()) { QLinkedList::const_iterator it, end; end = d->searchColumns.constEnd(); for(it = d->searchColumns.constBegin(); it != end; ++it) { if(*it < columnCount) { const QString & text = model()->data(parent.child(row, *it)).toString(); if(text.indexOf(s, 0, d->caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive) >= 0) return true; } } } else { for(int i = 0; i < columnCount; i++) { if(d->treeView->isColumnHidden(i) == false) { const QString & text = model()->data(parent.child(row, i)).toString(); if(text.indexOf(s, 0, d->caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive) >= 0) return true; } } } return false; } else { QString text = model()->data(item).toString(); if(text.indexOf(s, 0, d->caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive) >= 0) return true; else return false; } } void KViewSearchLine::contextMenuEvent( QContextMenuEvent*e ) { qDeleteAll(actions); QMenu *popup = KLineEdit::createStandardContextMenu(); if(d->treeView) { int columnCount = d->treeView->header()->count(); actions.resize(columnCount + 1); if(columnCount) { QMenu *submenu = new QMenu(i18n("Search Columns"), popup); popup->addMenu(submenu); bool allVisibleColumsCheked = true; QAction * allVisibleAct = new QAction(i18n("All Visible Columns"), nullptr); allVisibleAct->setCheckable(true); submenu->addAction(allVisibleAct); submenu->addSeparator(); for(int i=0; itreeView->header()->logicalIndex(i); QString columnText = model()->headerData(logicalIndex, Qt::Horizontal).toString(); if(columnText.isEmpty()) columnText = i18nc("Column number %1","Column No. %1", i); QAction * act = new QAction(columnText, nullptr); act->setCheckable(true); if( d->searchColumns.isEmpty() || d->searchColumns.contains(logicalIndex) ) act->setChecked(true); actions[logicalIndex] = act; if( !d->treeView || (d->treeView->isColumnHidden(i) == false) ) { submenu->addAction(act); allVisibleColumsCheked = allVisibleColumsCheked && act->isChecked(); } } actions[columnCount] = allVisibleAct; if(d->searchColumns.isEmpty() || allVisibleColumsCheked) { allVisibleAct->setChecked(true); d->searchColumns.clear(); } connect(submenu, &QMenu::triggered, this, &KViewSearchLine::searchColumnsMenuActivated); } } popup->exec( e->globalPos() ); delete popup; } //////////////////////////////////////////////////////////////////////////////// // protected slots //////////////////////////////////////////////////////////////////////////////// void KViewSearchLine::queueSearch(const QString &search) { d->queuedSearches++; d->search = search; QTimer::singleShot(200, this, &KViewSearchLine::activateSearch); } void KViewSearchLine::activateSearch() { --(d->queuedSearches); if(d->queuedSearches == 0) updateSearch(d->search); } //////////////////////////////////////////////////////////////////////////////// // private slots //////////////////////////////////////////////////////////////////////////////// void KViewSearchLine::listViewDeleted() { d->treeView = nullptr; d->listView = nullptr; setEnabled(false); } void KViewSearchLine::searchColumnsMenuActivated(QAction * action) { int index = 0; int count = actions.count(); for(int i=0; itreeView->header()->count(); if(index == columnCount) { if(d->searchColumns.isEmpty()) //all columns was checked d->searchColumns.append(0); else d->searchColumns.clear(); } else { if(d->searchColumns.contains(index)) d->searchColumns.removeAll(index); else { if(d->searchColumns.isEmpty()) //all columns was checked { for(int i=0; isearchColumns.append(i); } else d->searchColumns.append(index); } } updateSearch(); } void KViewSearchLine::slotRowsRemoved(const QModelIndex &parent, int, int) { if(!d->keepParentsVisible) return; QModelIndex p = parent; while(p.isValid()) { int count = model()->rowCount(p); if(count && anyVisible( model()->index(0,0, p), model()->index( count-1, 0, p))) return; if(itemMatches(p, d->search)) return; setVisible(p, false); p = p.parent(); } } void KViewSearchLine::slotColumnsInserted(const QModelIndex &, int, int ) { updateSearch(); } void KViewSearchLine::slotColumnsRemoved(const QModelIndex &, int first, int last) { if(d->treeView) updateSearch(); else { if(d->listView->modelColumn() >= first && d->listView->modelColumn()<= last) { if(d->listView->modelColumn()>last) qCritical()<<"Columns were removed, the modelColumn() doesn't exist anymore. " "K4listViewSearchLine can't cope with that."<listView) column = d->listView->modelColumn(); bool match = recheck( model()->index(topLeft.row(), column, parent), model()->index(bottomRight.row(), column, parent)); if(!d->keepParentsVisible) return; if(!parent.isValid()) // includes listview return; if(match) { QModelIndex p = parent; while(p.isValid()) { setVisible(p, true); p = p.parent(); } } else //no match => might need to hide parents (this is ugly) { if(isVisible(parent) == false) // parent is already hidden return; //parent is visible => implies all parents visible // first check if all of the unchanged rows are hidden match = false; if(topLeft.row() >= 1) match = match || anyVisible( model()->index(0,0, parent), model()->index(topLeft.row()-1, 0, parent)); int rowCount = model()->rowCount(parent); if(bottomRight.row() + 1 <= rowCount - 1) match = match || anyVisible( model()->index(bottomRight.row()+1, 0, parent), model()->index(rowCount-1, 0, parent)); if(!match) //all child rows hidden { if(itemMatches(parent, d->search)) return; // and parent didn't match, hide it setVisible(parent, false); // need to check all the way up to root QModelIndex p = parent.parent(); while(p.isValid()) { //hide p if no children of p isVisible and it doesn't match int count = model()->rowCount(p); if(anyVisible( model()->index(0, 0, p), model()->index(count-1, 0, p))) return; if(itemMatches(p, d->search)) return; setVisible(p, false); p = p.parent(); } } } } //////////////////////////////////////////////////////////////////////////////// // private methods //////////////////////////////////////////////////////////////////////////////// QAbstractItemModel * KViewSearchLine::model() const { if(d->treeView) return d->treeView->model(); else return d->listView->model(); } bool KViewSearchLine::anyVisible(const QModelIndex & first, const QModelIndex & last) { Q_ASSERT(d->treeView); QModelIndex index = first; while(true) { if( isVisible(index)) return true; if(index == last) break; index = nextRow(index); } return false; } bool KViewSearchLine::isVisible(const QModelIndex & index) { if(d->treeView) return !d->treeView->isRowHidden(index.row(), index.parent()); else return d->listView->isRowHidden(index.row()); } QModelIndex KViewSearchLine::nextRow(const QModelIndex & index) { return model()->index(index.row()+1, index.column(), index.parent()); } bool KViewSearchLine::recheck(const QModelIndex & first, const QModelIndex & last) { bool visible = false; QModelIndex index = first; while(true) { int rowCount = model()->rowCount(index); if(d->keepParentsVisible && rowCount && anyVisible( index.child(0,0), index.child( rowCount-1, 0))) { visible = true; } else // no children visible { bool match = itemMatches(index, d->search); setVisible(index, match); visible = visible || match; } if(index == last) break; index = nextRow(index); } return visible; } void KViewSearchLine::slotRowsInserted(const QModelIndex &parent, int first, int last) { bool visible = false; int column = 0; if(d->listView) column = d->listView->modelColumn(); QModelIndex index = model()->index(first, column, parent); QModelIndex end = model()->index(last, column, parent); while(true) { if(itemMatches(index, d->search)) { visible = true; setVisible(index, true); } else setVisible(index, false); if(index == end) break; index = nextRow(index); } if(!d->keepParentsVisible) return; if(visible) { QModelIndex p = parent; while(p.isValid()) { setVisible(p, true); p = p.parent(); } } } void KViewSearchLine::setVisible(const QModelIndex &index, bool v) { if(d->treeView) d->treeView->setRowHidden(index.row(), index.parent(), !v); else d->listView->setRowHidden(index.row(), !v); } void KViewSearchLine::checkItemParentsNotVisible() { int rowCount = model()->rowCount( QModelIndex() ); int column = 0; if(d->listView) column = d->listView->modelColumn(); for(int i = 0; i < rowCount; ++i) { QModelIndex it = model()->index(i, column, QModelIndex()); if(itemMatches(it, d->search)) setVisible(it, true); else setVisible(it, false); } } /** Check whether \p index, its siblings and their descendants should be shown. Show or hide the items as necessary. * * \p index The list view item to start showing / hiding items at. Typically, this is the first child of another item, or the * the first child of the list view. * \return \c true if an item which should be visible is found, \c false if all items found should be hidden. */ bool KViewSearchLine::checkItemParentsVisible(QModelIndex index) { bool visible = false; int rowCount = model()->rowCount(index.parent()); int column = 0; if(d->listView) column = d->listView->modelColumn(); for(int i = 0; iindex(i, column, index.parent()); if((model()->rowCount(index) && checkItemParentsVisible(index.child(0,column))) || itemMatches(index, d->search)) { visible = true; setVisible(index, true); } else setVisible(index, false); } return visible; } //////////////////////////////////////////////////////////////////////////////// // KViewSearchLineWidget //////////////////////////////////////////////////////////////////////////////// class KViewSearchLineWidget::KViewSearchLineWidgetPrivate { public: KViewSearchLineWidgetPrivate() : view(nullptr), searchLine(nullptr), layout(nullptr) {} QAbstractItemView *view; KViewSearchLine *searchLine; QHBoxLayout *layout; }; KViewSearchLineWidget::KViewSearchLineWidget(QAbstractItemView *view, QWidget *parent) : QWidget(parent) { d = new KViewSearchLineWidgetPrivate; d->view = view; QTimer::singleShot(0, this, &KViewSearchLineWidget::createWidgets); } KViewSearchLineWidget::~KViewSearchLineWidget() { delete d->layout; delete d; } KViewSearchLine *KViewSearchLineWidget::createSearchLine(QAbstractItemView *view) { if(!d->searchLine) d->searchLine = new KViewSearchLine(nullptr, view); return d->searchLine; } void KViewSearchLineWidget::createWidgets() { d->layout = new QHBoxLayout(this); - d->layout->setMargin(0); + d->layout->setContentsMargins(0, 0, 0, 0); QLabel *label = new QLabel(i18n("S&earch:")); label->setObjectName( QStringLiteral("kde toolbar widget" )); d->layout->addWidget(label); d->searchLine = createSearchLine(d->view); d->layout->addWidget(d->searchLine); d->searchLine->show(); label->setBuddy(d->searchLine); label->show(); } KViewSearchLine *KViewSearchLineWidget::searchLine() const { return d->searchLine; } diff --git a/src/toplevel.cpp b/src/toplevel.cpp index b58a2f9e8..620046281 100644 --- a/src/toplevel.cpp +++ b/src/toplevel.cpp @@ -1,474 +1,474 @@ /* This file is part of the KDE project Copyright (C) 2000 David Faure Copyright (C) 2002-2003 Alexander Kellett This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or at your option version 3 as published by the Free Software Foundation. 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "toplevel.h" #include #include "globalbookmarkmanager.h" #include "kbookmarkmodel/model.h" #include "bookmarkinfowidget.h" #include "actionsimpl.h" #include "exporters.h" #include "settings.h" #include "kbookmarkmodel/commands.h" #include "kbookmarkmodel/commandhistory.h" #include "kebsearchline.h" #include "bookmarklistview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include KEBApp *KEBApp::s_topLevel = nullptr; KEBApp::KEBApp( const QString &bookmarksFile, bool readonly, const QString &address, bool browser, const QString &caption, const QString &dbusObjectName ) : KXmlGuiWindow(), m_bookmarksFilename(bookmarksFile), m_caption(caption), m_dbusObjectName(dbusObjectName), m_readOnly(readonly),m_browser(browser) { QDBusConnection::sessionBus().registerObject(QStringLiteral("/keditbookmarks"), this, QDBusConnection::ExportScriptableSlots); Q_UNUSED(address);//FIXME sets the current item m_cmdHistory = new CommandHistory(this); m_cmdHistory->createActions(actionCollection()); connect(m_cmdHistory, &CommandHistory::notifyCommandExecuted, this, &KEBApp::notifyCommandExecuted); GlobalBookmarkManager::self()->createManager(m_bookmarksFilename, m_dbusObjectName, m_cmdHistory); s_topLevel = this; createActions(); if (m_browser) createGUI(); else createGUI(QStringLiteral("keditbookmarks-genui.rc")); connect(qApp->clipboard(), &QClipboard::dataChanged, this, &KEBApp::slotClipboardDataChanged); m_canPaste = false; mBookmarkListView = new BookmarkListView(); mBookmarkListView->setModel( GlobalBookmarkManager::self()->model() ); mBookmarkListView->setSelectionMode(QAbstractItemView::ExtendedSelection); mBookmarkListView->loadColumnSetting(); mBookmarkListView->loadFoldedState(); KViewSearchLineWidget *searchline = new KViewSearchLineWidget(mBookmarkListView, this); mBookmarkFolderView = new BookmarkFolderView(mBookmarkListView, this); mBookmarkFolderView->expandAll(); QWidget * rightSide = new QWidget; QVBoxLayout *listLayout = new QVBoxLayout(rightSide); - listLayout->setMargin(0); + listLayout->setContentsMargins(0, 0, 0, 0); rightSide->setLayout(listLayout); listLayout->addWidget(searchline); listLayout->addWidget(mBookmarkListView); m_bkinfo = new BookmarkInfoWidget(mBookmarkListView, GlobalBookmarkManager::self()->model()); listLayout->addWidget(m_bkinfo); QSplitter *hsplitter = new QSplitter(this); hsplitter->setOrientation(Qt::Horizontal); hsplitter->addWidget(mBookmarkFolderView); hsplitter->addWidget(rightSide); hsplitter->setStretchFactor(1,1); setCentralWidget(hsplitter); slotClipboardDataChanged(); setAutoSaveSettings(); connect(mBookmarkListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KEBApp::selectionChanged); connect(mBookmarkFolderView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KEBApp::selectionChanged); setCancelFavIconUpdatesEnabled(false); setCancelTestsEnabled(false); updateActions(); } void KEBApp::expandAll() { mBookmarkListView->expandAll(); } void KEBApp::collapseAll() { mBookmarkListView->collapseAll(); } QString KEBApp::bookmarkFilename() { return m_bookmarksFilename; } void KEBApp::reset(const QString & caption, const QString & bookmarksFileName) { //FIXME check this code, probably should be model()->setRoot instead of resetModel() m_caption = caption; m_bookmarksFilename = bookmarksFileName; GlobalBookmarkManager::self()->createManager(m_bookmarksFilename, m_dbusObjectName, m_cmdHistory); //FIXME this is still a memory leak (iff called by slotLoad) GlobalBookmarkManager::self()->model()->resetModel(); updateActions(); } void KEBApp::startEdit( Column c ) { const QModelIndexList & list = mBookmarkListView->selectionModel()->selectedIndexes(); QModelIndexList::const_iterator it, end; end = list.constEnd(); for(it = list.constBegin(); it != end; ++it) if( (*it).column() == int(c) && (mBookmarkListView->model()->flags(*it) & Qt::ItemIsEditable) ) mBookmarkListView->edit( *it ); } //FIXME clean up and remove unneeded things SelcAbilities KEBApp::getSelectionAbilities() const { SelcAbilities selctionAbilities; selctionAbilities.itemSelected = false; selctionAbilities.group = false; selctionAbilities.separator = false; selctionAbilities.urlIsEmpty = false; selctionAbilities.root = false; selctionAbilities.multiSelect = false; selctionAbilities.singleSelect = false; selctionAbilities.notEmpty = false; selctionAbilities.deleteEnabled = false; KBookmark nbk; QModelIndexList sel = mBookmarkListView->selectionModel()->selectedIndexes(); int columnCount; if(sel.count()) { nbk = mBookmarkListView->bookmarkForIndex(sel.first()); columnCount = mBookmarkListView->model()->columnCount(); } else { sel = mBookmarkFolderView->selectionModel()->selectedIndexes(); if(sel.count()) nbk = mBookmarkFolderView->bookmarkForIndex(sel.first()); columnCount = mBookmarkFolderView->model()->columnCount(); } if ( sel.count() > 0) { selctionAbilities.deleteEnabled = true; selctionAbilities.itemSelected = true; selctionAbilities.group = nbk.isGroup(); selctionAbilities.separator = nbk.isSeparator(); selctionAbilities.urlIsEmpty = nbk.url().isEmpty(); selctionAbilities.root = nbk.address() == GlobalBookmarkManager::self()->root().address(); selctionAbilities.multiSelect = (sel.count() > columnCount); selctionAbilities.singleSelect = (!selctionAbilities.multiSelect && selctionAbilities.itemSelected); } //FIXME check next line, if it actually works selctionAbilities.notEmpty = GlobalBookmarkManager::self()->root().first().hasParent(); /* //qDebug() <<"\nsa.itemSelected "<action(*it)->setEnabled(true); } } KBookmark KEBApp::firstSelected() const { QModelIndex index; const QModelIndexList & list = mBookmarkListView->selectionModel()->selectedIndexes(); if(list.count()) // selection in main listview, return bookmark for firstSelected return mBookmarkListView->bookmarkForIndex(*list.constBegin()); // no selection in main listview, fall back to selection in left tree const QModelIndexList & list2 = mBookmarkFolderView->selectionModel()->selectedIndexes(); return mBookmarkFolderView->bookmarkForIndex(*list2.constBegin()); } QString KEBApp::insertAddress() const { KBookmark current = firstSelected(); return (current.isGroup()) ? (current.address() + "/0") //FIXME internal representation used : KBookmark::nextAddress(current.address()); } static bool lessAddress(const QString& first, const QString& second) { QString a = first; QString b = second; if(a == b) return false; QString error(QStringLiteral("ERROR")); if(a == error) return false; if(b == error) return true; a += '/'; b += '/'; uint aLast = 0; uint bLast = 0; uint aEnd = a.length(); uint bEnd = b.length(); // Each iteration checks one "/"-delimeted part of the address // "" is treated correctly while(true) { // Invariant: a[0 ... aLast] == b[0 ... bLast] if(aLast + 1 == aEnd) //The last position was the last slash return true; // That means a is shorter than b if(bLast +1 == bEnd) return false; uint aNext = a.indexOf(QLatin1String("/"), aLast + 1); uint bNext = b.indexOf(QLatin1String("/"), bLast + 1); bool okay; uint aNum = a.midRef(aLast + 1, aNext - aLast - 1).toUInt(&okay); if(!okay) return false; uint bNum = b.midRef(bLast + 1, bNext - bLast - 1).toUInt(&okay); if(!okay) return true; if(aNum != bNum) return aNum < bNum; aLast = aNext; bLast = bNext; } } static bool lessBookmark(const KBookmark & first, const KBookmark & second) //FIXME Using internal represantation { return lessAddress(first.address(), second.address()); } KBookmark::List KEBApp::allBookmarks() const { KBookmark::List bookmarks; selectedBookmarksExpandedHelper(GlobalBookmarkManager::self()->root(), bookmarks); return bookmarks; } KBookmark::List KEBApp::selectedBookmarks() const { KBookmark::List bookmarks; const QModelIndexList & list = mBookmarkListView->selectionModel()->selectedIndexes(); if (!list.isEmpty()) { QModelIndexList::const_iterator it, end; end = list.constEnd(); for( it = list.constBegin(); it != end; ++it) { if((*it).column() != 0) continue; KBookmark bk = mBookmarkListView->bookmarkModel()->bookmarkForIndex(*it);; if(bk.address() != GlobalBookmarkManager::self()->root().address()) bookmarks.push_back( bk ); } qSort(bookmarks.begin(), bookmarks.end(), lessBookmark); } else { bookmarks.push_back(firstSelected()); } return bookmarks; } KBookmark::List KEBApp::selectedBookmarksExpanded() const { KBookmark::List bookmarks = selectedBookmarks(); KBookmark::List result; KBookmark::List::const_iterator it, end; end = bookmarks.constEnd(); for(it = bookmarks.constBegin(); it != end; ++it) { selectedBookmarksExpandedHelper( *it, result ); } return result; } void KEBApp::selectedBookmarksExpandedHelper(const KBookmark& bk, KBookmark::List & bookmarks) const { //FIXME in which order parents should ideally be: parent then child // or child and then parents if(bk.isGroup()) { KBookmarkGroup parent = bk.toGroup(); KBookmark child = parent.first(); while(!child.isNull()) { selectedBookmarksExpandedHelper(child, bookmarks); child = parent.next(child); } } else { bookmarks.push_back( bk ); } } KEBApp::~KEBApp() { // Save again, just in case the user expanded/collapsed folders (#131127) GlobalBookmarkManager::self()->notifyManagers(); s_topLevel = nullptr; delete m_cmdHistory; delete m_actionsImpl; delete mBookmarkListView; delete GlobalBookmarkManager::self(); } KToggleAction* KEBApp::getToggleAction(const char *action) const { return static_cast(actionCollection()->action(action)); } void KEBApp::resetActions() { stateChanged(QStringLiteral("disablestuff")); stateChanged(QStringLiteral("normal")); if (!m_readOnly) stateChanged(QStringLiteral("notreadonly")); } void KEBApp::selectionChanged() { updateActions(); } void KEBApp::updateActions() { resetActions(); setActionsEnabled(getSelectionAbilities()); } void KEBApp::slotClipboardDataChanged() { // //qDebug() << "KEBApp::slotClipboardDataChanged"; if (!m_readOnly) { m_canPaste = KBookmark::List::canDecode( QApplication::clipboard()->mimeData()); updateActions(); } } /* -------------------------- */ void KEBApp::notifyCommandExecuted() { // //qDebug() << "KEBApp::notifyCommandExecuted()"; updateActions(); } /* -------------------------- */ void KEBApp::slotConfigureToolbars() { //PORT TO QT5 saveMainWindowSettings(KConfigGroup( KSharedConfig::openConfig(), "MainWindow") ); KEditToolBar dlg(actionCollection(), this); connect(&dlg, &KEditToolBar::newToolBarConfig, this, &KEBApp::slotNewToolbarConfig); dlg.exec(); } void KEBApp::slotNewToolbarConfig() { // called when OK or Apply is clicked createGUI(); applyMainWindowSettings(KConfigGroup(KSharedConfig::openConfig(), "MainWindow") ); } /* -------------------------- */