|
|
|
/*
|
|
|
|
* Copyright (C) 2000 Matthias Elter <elter@kde.org>
|
|
|
|
* Copyright (C) 2001-2002 Raffaele Sandrini <sandrini@kde.org)
|
|
|
|
* Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
|
|
|
|
*
|
|
|
|
* 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <tqcstring.h>
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tqdatastream.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqdragobject.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <tqheader.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqpopupmenu.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kinputdialog.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <ksimpleconfig.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kdesktopfile.h>
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <kservice.h>
|
|
|
|
#include <kservicegroup.h>
|
|
|
|
#include <kmultipledrag.h>
|
|
|
|
#include <kurldrag.h>
|
|
|
|
|
|
|
|
#include "treeview.h"
|
|
|
|
#include "treeview.moc"
|
|
|
|
#include "khotkeys.h"
|
|
|
|
#include "menufile.h"
|
|
|
|
#include "menuinfo.h"
|
|
|
|
|
|
|
|
#define MOVE_FOLDER 'M'
|
|
|
|
#define COPY_FOLDER 'C'
|
|
|
|
#define MOVE_FILE 'm'
|
|
|
|
#define COPY_FILE 'c'
|
|
|
|
#define COPY_SEPARATOR 'S'
|
|
|
|
|
|
|
|
TreeItem::TreeItem(TQListViewItem *parent, TQListViewItem *after, const TQString& menuId, bool __init)
|
|
|
|
:TQListViewItem(parent, after), _hidden(false), _init(__init), _layoutDirty(false), _menuId(menuId),
|
|
|
|
m_folderInfo(0), m_entryInfo(0) {}
|
|
|
|
|
|
|
|
TreeItem::TreeItem(TQListView *parent, TQListViewItem *after, const TQString& menuId, bool __init)
|
|
|
|
: TQListViewItem(parent, after), _hidden(false), _init(__init), _layoutDirty(false), _menuId(menuId),
|
|
|
|
m_folderInfo(0), m_entryInfo(0) {}
|
|
|
|
|
|
|
|
void TreeItem::setName(const TQString &name)
|
|
|
|
{
|
|
|
|
_name = name;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeItem::setHidden(bool b)
|
|
|
|
{
|
|
|
|
if (_hidden == b) return;
|
|
|
|
_hidden = b;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeItem::update()
|
|
|
|
{
|
|
|
|
TQString s = _name;
|
|
|
|
if (_hidden)
|
|
|
|
s += i18n(" [Hidden]");
|
|
|
|
setText(0, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeItem::setOpen(bool o)
|
|
|
|
{
|
|
|
|
if (o)
|
|
|
|
load();
|
|
|
|
|
|
|
|
TQListViewItem::setOpen(o);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeItem::load()
|
|
|
|
{
|
|
|
|
if (m_folderInfo && !_init)
|
|
|
|
{
|
|
|
|
_init = true;
|
|
|
|
TreeView *tv = static_cast<TreeView *>(listView());
|
|
|
|
tv->fillBranch(m_folderInfo, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeItem::paintCell ( TQPainter * p, const TQColorGroup & cg, int column, int width, int align )
|
|
|
|
{
|
|
|
|
TQListViewItem::paintCell(p, cg, column, width, align);
|
|
|
|
|
|
|
|
if (!m_folderInfo && !m_entryInfo)
|
|
|
|
{
|
|
|
|
// Draw Separator
|
|
|
|
int h = (height() / 2) -1;
|
|
|
|
if (isSelected())
|
|
|
|
p->setPen( cg.highlightedText() );
|
|
|
|
else
|
|
|
|
p->setPen( cg.text() );
|
|
|
|
p->drawLine(0, h,
|
|
|
|
width, h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeItem::setup()
|
|
|
|
{
|
|
|
|
TQListViewItem::setup();
|
|
|
|
if (!m_folderInfo && !m_entryInfo)
|
|
|
|
setHeight(8);
|
|
|
|
}
|
|
|
|
|
|
|
|
static TQPixmap appIcon(const TQString &iconName)
|
|
|
|
{
|
|
|
|
TQPixmap normal = KGlobal::iconLoader()->loadIcon(iconName, KIcon::Small, 0, KIcon::DefaultState, 0L, true);
|
|
|
|
// make sure they are not larger than 20x20
|
|
|
|
if (normal.width() > 20 || normal.height() > 20)
|
|
|
|
{
|
|
|
|
TQImage tmp = normal.convertToImage();
|
|
|
|
tmp = tmp.smoothScale(20, 20);
|
|
|
|
normal.convertFromImage(tmp);
|
|
|
|
}
|
|
|
|
return normal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TreeView::TreeView( bool controlCenter, KActionCollection *ac, TQWidget *parent, const char *name )
|
|
|
|
: KListView(parent, name), m_ac(ac), m_rmb(0), m_clipboard(0),
|
|
|
|
m_clipboardFolderInfo(0), m_clipboardEntryInfo(0),
|
|
|
|
m_controlCenter(controlCenter), m_layoutDirty(false)
|
|
|
|
{
|
|
|
|
setFrameStyle(TQFrame::WinPanel | TQFrame::Sunken);
|
|
|
|
setAllColumnsShowFocus(true);
|
|
|
|
setRootIsDecorated(true);
|
|
|
|
setSorting(-1);
|
|
|
|
setAcceptDrops(true);
|
|
|
|
setDropVisualizer(true);
|
|
|
|
setDragEnabled(true);
|
|
|
|
setMinimumWidth(240);
|
|
|
|
|
|
|
|
addColumn("");
|
|
|
|
header()->hide();
|
|
|
|
|
|
|
|
connect(this, TQT_SIGNAL(dropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)),
|
|
|
|
TQT_SLOT(slotDropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)));
|
|
|
|
|
|
|
|
connect(this, TQT_SIGNAL(clicked( TQListViewItem* )),
|
|
|
|
TQT_SLOT(itemSelected( TQListViewItem* )));
|
|
|
|
|
|
|
|
connect(this,TQT_SIGNAL(selectionChanged ( TQListViewItem * )),
|
|
|
|
TQT_SLOT(itemSelected( TQListViewItem* )));
|
|
|
|
|
|
|
|
connect(this, TQT_SIGNAL(rightButtonPressed(TQListViewItem*, const TQPoint&, int)),
|
|
|
|
TQT_SLOT(slotRMBPressed(TQListViewItem*, const TQPoint&)));
|
|
|
|
|
|
|
|
// connect actions
|
|
|
|
connect(m_ac->action("newitem"), TQT_SIGNAL(activated()), TQT_SLOT(newitem()));
|
|
|
|
connect(m_ac->action("newsubmenu"), TQT_SIGNAL(activated()), TQT_SLOT(newsubmenu()));
|
|
|
|
if (m_ac->action("newsep"))
|
|
|
|
connect(m_ac->action("newsep"), TQT_SIGNAL(activated()), TQT_SLOT(newsep()));
|
|
|
|
|
|
|
|
m_menuFile = new MenuFile( locateLocal("xdgconf-menu", "applications-kmenuedit.menu"));
|
|
|
|
m_rootFolder = new MenuFolderInfo;
|
|
|
|
m_separator = new MenuSeparatorInfo;
|
|
|
|
m_drag = 0;
|
|
|
|
|
|
|
|
// Read menu format configuration information
|
|
|
|
KSharedConfig::Ptr pConfig = KSharedConfig::openConfig("kickerrc");
|
|
|
|
|
|
|
|
pConfig->setGroup("menus");
|
|
|
|
m_detailedMenuEntries = pConfig->readBoolEntry("DetailedMenuEntries",true);
|
|
|
|
if (m_detailedMenuEntries)
|
|
|
|
{
|
|
|
|
m_detailedEntriesNamesFirst = pConfig->readBoolEntry("DetailedEntriesNamesFirst",false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TreeView::~TreeView() {
|
|
|
|
cleanupClipboard();
|
|
|
|
delete m_rootFolder;
|
|
|
|
delete m_separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::setViewMode(bool showHidden)
|
|
|
|
{
|
|
|
|
delete m_rmb;
|
|
|
|
|
|
|
|
// setup rmb menu
|
|
|
|
m_rmb = new TQPopupMenu(this);
|
|
|
|
KAction *action;
|
|
|
|
|
|
|
|
action = m_ac->action("edit_cut");
|
|
|
|
if(action) {
|
|
|
|
action->plug(m_rmb);
|
|
|
|
action->setEnabled(false);
|
|
|
|
connect(action, TQT_SIGNAL(activated()), TQT_SLOT(cut()));
|
|
|
|
}
|
|
|
|
|
|
|
|
action = m_ac->action("edit_copy");
|
|
|
|
if(action) {
|
|
|
|
action->plug(m_rmb);
|
|
|
|
action->setEnabled(false);
|
|
|
|
connect(action, TQT_SIGNAL(activated()), TQT_SLOT(copy()));
|
|
|
|
}
|
|
|
|
|
|
|
|
action = m_ac->action("edit_paste");
|
|
|
|
if(action) {
|
|
|
|
action->plug(m_rmb);
|
|
|
|
action->setEnabled(false);
|
|
|
|
connect(action, TQT_SIGNAL(activated()), TQT_SLOT(paste()));
|
|
|
|
}
|
|
|
|
|
|
|
|
m_rmb->insertSeparator();
|
|
|
|
|
|
|
|
action = m_ac->action("delete");
|
|
|
|
if(action) {
|
|
|
|
action->plug(m_rmb);
|
|
|
|
action->setEnabled(false);
|
|
|
|
connect(action, TQT_SIGNAL(activated()), TQT_SLOT(del()));
|
|
|
|
}
|
|
|
|
|
|
|
|
m_rmb->insertSeparator();
|
|
|
|
|
|
|
|
if(m_ac->action("newitem"))
|
|
|
|
m_ac->action("newitem")->plug(m_rmb);
|
|
|
|
if(m_ac->action("newsubmenu"))
|
|
|
|
m_ac->action("newsubmenu")->plug(m_rmb);
|
|
|
|
if(m_ac->action("newsep"))
|
|
|
|
m_ac->action("newsep")->plug(m_rmb);
|
|
|
|
|
|
|
|
m_showHidden = showHidden;
|
|
|
|
readMenuFolderInfo();
|
|
|
|
fill();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::readMenuFolderInfo(MenuFolderInfo *folderInfo, KServiceGroup::Ptr folder, const TQString &prefix)
|
|
|
|
{
|
|
|
|
if (!folderInfo)
|
|
|
|
{
|
|
|
|
folderInfo = m_rootFolder;
|
|
|
|
if (m_controlCenter)
|
|
|
|
folder = KServiceGroup::baseGroup("settings");
|
|
|
|
else
|
|
|
|
folder = KServiceGroup::root();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!folder || !folder->isValid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
folderInfo->caption = folder->caption();
|
|
|
|
folderInfo->comment = folder->comment();
|
|
|
|
|
|
|
|
// Item names may contain ampersands. To avoid them being converted
|
|
|
|
// to accelerators, replace them with two ampersands.
|
|
|
|
folderInfo->hidden = folder->noDisplay();
|
|
|
|
folderInfo->directoryFile = folder->directoryEntryPath();
|
|
|
|
folderInfo->icon = folder->icon();
|
|
|
|
TQString id = folder->relPath();
|
|
|
|
int i = id.findRev('/', -2);
|
|
|
|
id = id.mid(i+1);
|
|
|
|
folderInfo->id = id;
|
|
|
|
folderInfo->fullId = prefix + id;
|
|
|
|
|
|
|
|
KServiceGroup::List list = folder->entries(true, !m_showHidden, true, m_detailedMenuEntries && !m_detailedEntriesNamesFirst);
|
|
|
|
|
|
|
|
for(KServiceGroup::List::ConstIterator it = list.begin();
|
|
|
|
it != list.end(); ++it)
|
|
|
|
{
|
|
|
|
KSycocaEntry * e = *it;
|
|
|
|
|
|
|
|
if (e->isType(KST_KServiceGroup))
|
|
|
|
{
|
|
|
|
KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
|
|
|
|
MenuFolderInfo *subFolderInfo = new MenuFolderInfo();
|
|
|
|
readMenuFolderInfo(subFolderInfo, g, folderInfo->fullId);
|
|
|
|
folderInfo->add(subFolderInfo, true);
|
|
|
|
}
|
|
|
|
else if (e->isType(KST_KService))
|
|
|
|
{
|
|
|
|
folderInfo->add(new MenuEntryInfo(static_cast<KService *>(e)), true);
|
|
|
|
}
|
|
|
|
else if (e->isType(KST_KServiceSeparator))
|
|
|
|
{
|
|
|
|
folderInfo->add(m_separator, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::fill()
|
|
|
|
{
|
|
|
|
TQApplication::setOverrideCursor(Qt::WaitCursor);
|
|
|
|
clear();
|
|
|
|
fillBranch(m_rootFolder, 0);
|
|
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString TreeView::findName(KDesktopFile *df, bool deleted)
|
|
|
|
{
|
|
|
|
TQString name = df->readName();
|
|
|
|
if (deleted)
|
|
|
|
{
|
|
|
|
if (name == "empty")
|
|
|
|
name = TQString::null;
|
|
|
|
if (name.isEmpty())
|
|
|
|
{
|
|
|
|
TQString file = df->fileName();
|
|
|
|
TQString res = df->resource();
|
|
|
|
|
|
|
|
bool isLocal = true;
|
|
|
|
TQStringList files = KGlobal::dirs()->findAllResources(res.latin1(), file);
|
|
|
|
for(TQStringList::ConstIterator it = files.begin();
|
|
|
|
it != files.end();
|
|
|
|
++it)
|
|
|
|
{
|
|
|
|
if (isLocal)
|
|
|
|
{
|
|
|
|
isLocal = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDesktopFile df2(*it);
|
|
|
|
name = df2.readName();
|
|
|
|
|
|
|
|
if (!name.isEmpty() && (name != "empty"))
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
TreeItem *TreeView::createTreeItem(TreeItem *parent, TQListViewItem *after, MenuFolderInfo *folderInfo, bool _init)
|
|
|
|
{
|
|
|
|
TreeItem *item;
|
|
|
|
if (parent == 0)
|
|
|
|
item = new TreeItem(this, after, TQString::null, _init);
|
|
|
|
else
|
|
|
|
item = new TreeItem(parent, after, TQString::null, _init);
|
|
|
|
|
|
|
|
item->setMenuFolderInfo(folderInfo);
|
|
|
|
item->setName(folderInfo->caption);
|
|
|
|
item->setPixmap(0, appIcon(folderInfo->icon));
|
|
|
|
item->setDirectoryPath(folderInfo->fullId);
|
|
|
|
item->setHidden(folderInfo->hidden);
|
|
|
|
item->setExpandable(true);
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
TreeItem *TreeView::createTreeItem(TreeItem *parent, TQListViewItem *after, MenuEntryInfo *entryInfo, bool _init)
|
|
|
|
{
|
|
|
|
bool hidden = entryInfo->hidden;
|
|
|
|
|
|
|
|
TreeItem* item;
|
|
|
|
if (parent == 0)
|
|
|
|
item = new TreeItem(this, after, entryInfo->menuId(), _init);
|
|
|
|
else
|
|
|
|
item = new TreeItem(parent, after, entryInfo->menuId(),_init);
|
|
|
|
|
|
|
|
QString name;
|
|
|
|
|
|
|
|
if (m_detailedMenuEntries && entryInfo->description.length() != 0)
|
|
|
|
{
|
|
|
|
if (m_detailedEntriesNamesFirst)
|
|
|
|
{
|
|
|
|
name = entryInfo->caption + " (" + entryInfo->description + ")";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
name = entryInfo->description + " (" + entryInfo->caption + ")";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
name = entryInfo->caption;
|
|
|
|
}
|
|
|
|
item->setMenuEntryInfo(entryInfo);
|
|
|
|
item->setName(name);
|
|
|
|
item->setPixmap(0, appIcon(entryInfo->icon));
|
|
|
|
|
|
|
|
item->setHidden(hidden);
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
TreeItem *TreeView::createTreeItem(TreeItem *parent, TQListViewItem *after, MenuSeparatorInfo *, bool _init)
|
|
|
|
{
|
|
|
|
TreeItem* item;
|
|
|
|
if (parent == 0)
|
|
|
|
item = new TreeItem(this, after, TQString::null, _init);
|
|
|
|
else
|
|
|
|
item = new TreeItem(parent, after, TQString::null,_init);
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::fillBranch(MenuFolderInfo *folderInfo, TreeItem *parent)
|
|
|
|
{
|
|
|
|
TQString relPath = parent ? parent->directory() : TQString::null;
|
|
|
|
TQPtrListIterator<MenuInfo> it( folderInfo->initialLayout );
|
|
|
|
TreeItem *after = 0;
|
|
|
|
for (MenuInfo *info; (info = it.current()); ++it)
|
|
|
|
{
|
|
|
|
MenuEntryInfo *entry = dynamic_cast<MenuEntryInfo*>(info);
|
|
|
|
if (entry)
|
|
|
|
{
|
|
|
|
after = createTreeItem(parent, after, entry);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
MenuFolderInfo *subFolder = dynamic_cast<MenuFolderInfo*>(info);
|
|
|
|
if (subFolder)
|
|
|
|
{
|
|
|
|
after = createTreeItem(parent, after, subFolder);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
MenuSeparatorInfo *separator = dynamic_cast<MenuSeparatorInfo*>(info);
|
|
|
|
if (separator)
|
|
|
|
{
|
|
|
|
after = createTreeItem(parent, after, separator);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::closeAllItems(TQListViewItem *item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
while(item)
|
|
|
|
{
|
|
|
|
item->setOpen(false);
|
|
|
|
closeAllItems(item->firstChild());
|
|
|
|
item = item->nextSibling();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::selectMenu(const TQString &menu)
|
|
|
|
{
|
|
|
|
closeAllItems(firstChild());
|
|
|
|
|
|
|
|
if (menu.length() <= 1)
|
|
|
|
{
|
|
|
|
setCurrentItem(firstChild());
|
|
|
|
clearSelection();
|
|
|
|
return; // Root menu
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString restMenu = menu.mid(1);
|
|
|
|
if (!restMenu.endsWith("/"))
|
|
|
|
restMenu += "/";
|
|
|
|
|
|
|
|
TreeItem *item = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
int i = restMenu.find("/");
|
|
|
|
TQString subMenu = restMenu.left(i+1);
|
|
|
|
restMenu = restMenu.mid(i+1);
|
|
|
|
|
|
|
|
item = (TreeItem*)(item ? item->firstChild() : firstChild());
|
|
|
|
while(item)
|
|
|
|
{
|
|
|
|
MenuFolderInfo *folderInfo = item->folderInfo();
|
|
|
|
if (folderInfo && (folderInfo->id == subMenu))
|
|
|
|
{
|
|
|
|
item->setOpen(true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
item = (TreeItem*) item->nextSibling();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while( item && !restMenu.isEmpty());
|
|
|
|
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
setCurrentItem(item);
|
|
|
|
ensureItemVisible(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::selectMenuEntry(const TQString &menuEntry)
|
|
|
|
{
|
|
|
|
TreeItem *item = (TreeItem *) selectedItem();
|
|
|
|
if (!item)
|
|
|
|
{
|
|
|
|
item = (TreeItem *) currentItem();
|
|
|
|
while (item && item->isDirectory())
|
|
|
|
item = (TreeItem*) item->nextSibling();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
item = (TreeItem *) item->firstChild();
|
|
|
|
|
|
|
|
while(item)
|
|
|
|
{
|
|
|
|
MenuEntryInfo *entry = item->entryInfo();
|
|
|
|
if (entry && (entry->menuId() == menuEntry))
|
|
|
|
{
|
|
|
|
setCurrentItem(item);
|
|
|
|
ensureItemVisible(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
item = (TreeItem*) item->nextSibling();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::itemSelected(TQListViewItem *item)
|
|
|
|
{
|
|
|
|
TreeItem *_item = (TreeItem*)item;
|
|
|
|
bool selected = false;
|
|
|
|
bool dselected = false;
|
|
|
|
if (_item) {
|
|
|
|
selected = true;
|
|
|
|
dselected = _item->isHidden();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ac->action("edit_cut")->setEnabled(selected);
|
|
|
|
m_ac->action("edit_copy")->setEnabled(selected);
|
|
|
|
|
|
|
|
if (m_ac->action("delete"))
|
|
|
|
m_ac->action("delete")->setEnabled(selected && !dselected);
|
|
|
|
|
|
|
|
if(!item)
|
|
|
|
{
|
|
|
|
emit disableAction();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_item->isDirectory())
|
|
|
|
emit entrySelected(_item->folderInfo());
|
|
|
|
else
|
|
|
|
emit entrySelected(_item->entryInfo());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::currentChanged(MenuFolderInfo *folderInfo)
|
|
|
|
{
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
if (item == 0) return;
|
|
|
|
if (folderInfo == 0) return;
|
|
|
|
|
|
|
|
item->setName(folderInfo->caption);
|
|
|
|
item->setPixmap(0, appIcon(folderInfo->icon));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::currentChanged(MenuEntryInfo *entryInfo)
|
|
|
|
{
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
if (item == 0) return;
|
|
|
|
if (entryInfo == 0) return;
|
|
|
|
|
|
|
|
QString name;
|
|
|
|
|
|
|
|
if (m_detailedMenuEntries && entryInfo->description.length() != 0)
|
|
|
|
{
|
|
|
|
if (m_detailedEntriesNamesFirst)
|
|
|
|
{
|
|
|
|
name = entryInfo->caption + " (" + entryInfo->description + ")";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
name = entryInfo->description + " (" + entryInfo->caption + ")";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
name = entryInfo->caption;
|
|
|
|
}
|
|
|
|
item->setName(name);
|
|
|
|
item->setPixmap(0, appIcon(entryInfo->icon));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList TreeView::fileList(const TQString& rPath)
|
|
|
|
{
|
|
|
|
TQString relativePath = rPath;
|
|
|
|
|
|
|
|
// truncate "/.directory"
|
|
|
|
int pos = relativePath.findRev("/.directory");
|
|
|
|
if (pos > 0) relativePath.truncate(pos);
|
|
|
|
|
|
|
|
TQStringList filelist;
|
|
|
|
|
|
|
|
// loop through all resource dirs and build a file list
|
|
|
|
TQStringList resdirlist = KGlobal::dirs()->resourceDirs("apps");
|
|
|
|
for (TQStringList::ConstIterator it = resdirlist.begin(); it != resdirlist.end(); ++it)
|
|
|
|
{
|
|
|
|
TQDir dir((*it) + "/" + relativePath);
|
|
|
|
if(!dir.exists()) continue;
|
|
|
|
|
|
|
|
dir.setFilter(TQDir::Files);
|
|
|
|
dir.setNameFilter("*.desktop;*.kdelnk");
|
|
|
|
|
|
|
|
// build a list of files
|
|
|
|
TQStringList files = dir.entryList();
|
|
|
|
for (TQStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
|
|
|
|
// does not work?!
|
|
|
|
//if (filelist.contains(*it)) continue;
|
|
|
|
|
|
|
|
if (relativePath.isEmpty()) {
|
|
|
|
filelist.remove(*it); // hack
|
|
|
|
filelist.append(*it);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
filelist.remove(relativePath + "/" + *it); //hack
|
|
|
|
filelist.append(relativePath + "/" + *it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return filelist;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList TreeView::dirList(const TQString& rPath)
|
|
|
|
{
|
|
|
|
TQString relativePath = rPath;
|
|
|
|
|
|
|
|
// truncate "/.directory"
|
|
|
|
int pos = relativePath.findRev("/.directory");
|
|
|
|
if (pos > 0) relativePath.truncate(pos);
|
|
|
|
|
|
|
|
TQStringList dirlist;
|
|
|
|
|
|
|
|
// loop through all resource dirs and build a subdir list
|
|
|
|
TQStringList resdirlist = KGlobal::dirs()->resourceDirs("apps");
|
|
|
|
for (TQStringList::ConstIterator it = resdirlist.begin(); it != resdirlist.end(); ++it)
|
|
|
|
{
|
|
|
|
TQDir dir((*it) + "/" + relativePath);
|
|
|
|
if(!dir.exists()) continue;
|
|
|
|
dir.setFilter(TQDir::Dirs);
|
|
|
|
|
|
|
|
// build a list of subdirs
|
|
|
|
TQStringList subdirs = dir.entryList();
|
|
|
|
for (TQStringList::ConstIterator it = subdirs.begin(); it != subdirs.end(); ++it) {
|
|
|
|
if ((*it) == "." || (*it) == "..") continue;
|
|
|
|
// does not work?!
|
|
|
|
// if (dirlist.contains(*it)) continue;
|
|
|
|
|
|
|
|
if (relativePath.isEmpty()) {
|
|
|
|
dirlist.remove(*it); //hack
|
|
|
|
dirlist.append(*it);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
dirlist.remove(relativePath + "/" + *it); //hack
|
|
|
|
dirlist.append(relativePath + "/" + *it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dirlist;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TreeView::acceptDrag(TQDropEvent* e) const
|
|
|
|
{
|
|
|
|
if (e->provides("application/x-kmenuedit-internal") &&
|
|
|
|
(e->source() == const_cast<TreeView *>(this)))
|
|
|
|
return true;
|
|
|
|
KURL::List urls;
|
|
|
|
if (KURLDrag::decode(e, urls) && (urls.count() == 1) &&
|
|
|
|
urls[0].isLocalFile() && urls[0].path().endsWith(".desktop"))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static TQString createDesktopFile(const TQString &file, TQString *menuId, TQStringList *excludeList)
|
|
|
|
{
|
|
|
|
TQString base = file.mid(file.findRev('/')+1);
|
|
|
|
base = base.left(base.findRev('.'));
|
|
|
|
|
|
|
|
TQRegExp r("(.*)(?=-\\d+)");
|
|
|
|
base = (r.search(base) > -1) ? r.cap(1) : base;
|
|
|
|
|
|
|
|
TQString result = KService::newServicePath(true, base, menuId, excludeList);
|
|
|
|
excludeList->append(*menuId);
|
|
|
|
// Todo for Undo-support: Undo menuId allocation:
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static KDesktopFile *copyDesktopFile(MenuEntryInfo *entryInfo, TQString *menuId, TQStringList *excludeList)
|
|
|
|
{
|
|
|
|
TQString result = createDesktopFile(entryInfo->file(), menuId, excludeList);
|
|
|
|
KDesktopFile *df = entryInfo->desktopFile()->copyTo(result);
|
|
|
|
df->deleteEntry("Categories"); // Don't set any categories!
|
|
|
|
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
static TQString createDirectoryFile(const TQString &file, TQStringList *excludeList)
|
|
|
|
{
|
|
|
|
TQString base = file.mid(file.findRev('/')+1);
|
|
|
|
base = base.left(base.findRev('.'));
|
|
|
|
|
|
|
|
TQString result;
|
|
|
|
int i = 1;
|
|
|
|
while(true)
|
|
|
|
{
|
|
|
|
if (i == 1)
|
|
|
|
result = base + ".directory";
|
|
|
|
else
|
|
|
|
result = base + TQString("-%1.directory").arg(i);
|
|
|
|
|
|
|
|
if (!excludeList->contains(result))
|
|
|
|
{
|
|
|
|
if (locate("xdgdata-dirs", result).isEmpty())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
excludeList->append(result);
|
|
|
|
result = locateLocal("xdgdata-dirs", result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TreeView::slotDropped (TQDropEvent * e, TQListViewItem *parent, TQListViewItem*after)
|
|
|
|
{
|
|
|
|
if(!e) return;
|
|
|
|
|
|
|
|
// get destination folder
|
|
|
|
TreeItem *parentItem = static_cast<TreeItem*>(parent);
|
|
|
|
TQString folder = parentItem ? parentItem->directory() : TQString::null;
|
|
|
|
MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
|
|
|
|
|
|
|
|
if (e->source() != this)
|
|
|
|
{
|
|
|
|
// External drop
|
|
|
|
KURL::List urls;
|
|
|
|
if (!KURLDrag::decode(e, urls) || (urls.count() != 1) || !urls[0].isLocalFile())
|
|
|
|
return;
|
|
|
|
TQString path = urls[0].path();
|
|
|
|
if (!path.endsWith(".desktop"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQString menuId;
|
|
|
|
TQString result = createDesktopFile(path, &menuId, &m_newMenuIds);
|
|
|
|
KDesktopFile orig_df(path);
|
|
|
|
KDesktopFile *df = orig_df.copyTo(result);
|
|
|
|
df->deleteEntry("Categories"); // Don't set any categories!
|
|
|
|
|
|
|
|
KService *s = new KService(df);
|
|
|
|
s->setMenuId(menuId);
|
|
|
|
|
|
|
|
MenuEntryInfo *entryInfo = new MenuEntryInfo(s, df);
|
|
|
|
|
|
|
|
TQString oldCaption = entryInfo->caption;
|
|
|
|
TQString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
|
|
|
|
entryInfo->setCaption(newCaption);
|
|
|
|
|
|
|
|
// Add file to menu
|
|
|
|
// m_menuFile->addEntry(folder, menuId);
|
|
|
|
m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
|
|
|
|
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
// update fileInfo data
|
|
|
|
parentFolderInfo->add(entryInfo);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, after, entryInfo, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
|
|
|
|
m_drag = 0;
|
|
|
|
setLayoutDirty(parentItem);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// is there content in the clipboard?
|
|
|
|
if (!m_drag) return;
|
|
|
|
|
|
|
|
if (m_dragItem == after) return; // Nothing to do
|
|
|
|
|
|
|
|
int command = m_drag;
|
|
|
|
if (command == MOVE_FOLDER)
|
|
|
|
{
|
|
|
|
MenuFolderInfo *folderInfo = m_dragInfo;
|
|
|
|
if (e->action() == TQDropEvent::Copy)
|
|
|
|
{
|
|
|
|
// Ugh.. this is hard :)
|
|
|
|
// * Create new .directory file
|
|
|
|
// Add
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TreeItem *tmpItem = static_cast<TreeItem*>(parentItem);
|
|
|
|
while ( tmpItem )
|
|
|
|
{
|
|
|
|
if ( tmpItem == m_dragItem )
|
|
|
|
{
|
|
|
|
m_drag = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
tmpItem = static_cast<TreeItem*>(tmpItem->parent() );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove MenuFolderInfo
|
|
|
|
TreeItem *oldParentItem = static_cast<TreeItem*>(m_dragItem->parent());
|
|
|
|
MenuFolderInfo *oldParentFolderInfo = oldParentItem ? oldParentItem->folderInfo() : m_rootFolder;
|
|
|
|
oldParentFolderInfo->take(folderInfo);
|
|
|
|
|
|
|
|
// Move menu
|
|
|
|
TQString oldFolder = folderInfo->fullId;
|
|
|
|
TQString folderName = folderInfo->id;
|
|
|
|
TQString newFolder = m_menuFile->uniqueMenuName(folder, folderName, parentFolderInfo->existingMenuIds());
|
|
|
|
folderInfo->id = newFolder;
|
|
|
|
|
|
|
|
// Add file to menu
|
|
|
|
//m_menuFile->moveMenu(oldFolder, folder + newFolder);
|
|
|
|
m_menuFile->pushAction(MenuFile::MOVE_MENU, oldFolder, folder + newFolder);
|
|
|
|
|
|
|
|
// Make sure caption is unique
|
|
|
|
TQString newCaption = parentFolderInfo->uniqueMenuCaption(folderInfo->caption);
|
|
|
|
if (newCaption != folderInfo->caption)
|
|
|
|
{
|
|
|
|
folderInfo->setCaption(newCaption);
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
// update fileInfo data
|
|
|
|
folderInfo->updateFullId(parentFolderInfo->fullId);
|
|
|
|
folderInfo->setInUse(true);
|
|
|
|
parentFolderInfo->add(folderInfo);
|
|
|
|
|
|
|
|
if ((parentItem != oldParentItem) || !after)
|
|
|
|
{
|
|
|
|
if (oldParentItem)
|
|
|
|
oldParentItem->takeItem(m_dragItem);
|
|
|
|
else
|
|
|
|
takeItem(m_dragItem);
|
|
|
|
if (parentItem)
|
|
|
|
parentItem->insertItem(m_dragItem);
|
|
|
|
else
|
|
|
|
insertItem(m_dragItem);
|
|
|
|
}
|
|
|
|
m_dragItem->moveItem(after);
|
|
|
|
m_dragItem->setName(folderInfo->caption);
|
|
|
|
m_dragItem->setDirectoryPath(folderInfo->fullId);
|
|
|
|
setSelected(m_dragItem, true);
|
|
|
|
itemSelected(m_dragItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (command == MOVE_FILE)
|
|
|
|
{
|
|
|
|
MenuEntryInfo *entryInfo = m_dragItem->entryInfo();
|
|
|
|
TQString menuId = entryInfo->menuId();
|
|
|
|
|
|
|
|
if (e->action() == TQDropEvent::Copy)
|
|
|
|
{
|
|
|
|
|
|
|
|
// Need to copy file and then add it
|
|
|
|
KDesktopFile *df = copyDesktopFile(entryInfo, &menuId, &m_newMenuIds); // Duplicate
|
|
|
|
//UNDO-ACTION: NEW_MENU_ID (menuId)
|
|
|
|
|
|
|
|
KService *s = new KService(df);
|
|
|
|
s->setMenuId(menuId);
|
|
|
|
|
|
|
|
entryInfo = new MenuEntryInfo(s, df);
|
|
|
|
|
|
|
|
TQString oldCaption = entryInfo->caption;
|
|
|
|
TQString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
|
|
|
|
entryInfo->setCaption(newCaption);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
del(m_dragItem, false);
|
|
|
|
TQString oldCaption = entryInfo->caption;
|
|
|
|
TQString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption);
|
|
|
|
entryInfo->setCaption(newCaption);
|
|
|
|
entryInfo->setInUse(true);
|
|
|
|
}
|
|
|
|
// Add file to menu
|
|
|
|
// m_menuFile->addEntry(folder, menuId);
|
|
|
|
m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
|
|
|
|
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
// update fileInfo data
|
|
|
|
parentFolderInfo->add(entryInfo);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, after, entryInfo, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
}
|
|
|
|
else if (command == COPY_SEPARATOR)
|
|
|
|
{
|
|
|
|
if (e->action() != TQDropEvent::Copy)
|
|
|
|
del(m_dragItem, false);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, after, m_separator, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Error
|
|
|
|
}
|
|
|
|
m_drag = 0;
|
|
|
|
setLayoutDirty(parentItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TreeView::startDrag()
|
|
|
|
{
|
|
|
|
TQDragObject *drag = dragObject();
|
|
|
|
|
|
|
|
if (!drag)
|
|
|
|
return;
|
|
|
|
|
|
|
|
drag->dragMove();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDragObject *TreeView::dragObject()
|
|
|
|
{
|
|
|
|
m_dragPath = TQString::null;
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
if(item == 0) return 0;
|
|
|
|
|
|
|
|
KMultipleDrag *drag = new KMultipleDrag( this );
|
|
|
|
|
|
|
|
if (item->isDirectory())
|
|
|
|
{
|
|
|
|
m_drag = MOVE_FOLDER;
|
|
|
|
m_dragInfo = item->folderInfo();
|
|
|
|
m_dragItem = item;
|
|
|
|
}
|
|
|
|
else if (item->isEntry())
|
|
|
|
{
|
|
|
|
m_drag = MOVE_FILE;
|
|
|
|
m_dragInfo = 0;
|
|
|
|
m_dragItem = item;
|
|
|
|
TQString menuId = item->menuId();
|
|
|
|
m_dragPath = item->entryInfo()->service->desktopEntryPath();
|
|
|
|
if (!m_dragPath.isEmpty())
|
|
|
|
m_dragPath = locate("apps", m_dragPath);
|
|
|
|
if (!m_dragPath.isEmpty())
|
|
|
|
{
|
|
|
|
KURL url;
|
|
|
|
url.setPath(m_dragPath);
|
|
|
|
drag->addDragObject( new KURLDrag(url, 0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_drag = COPY_SEPARATOR;
|
|
|
|
m_dragInfo = 0;
|
|
|
|
m_dragItem = item;
|
|
|
|
}
|
|
|
|
|
|
|
|
drag->addDragObject( new TQStoredDrag("application/x-kmenuedit-internal", 0));
|
|
|
|
if ( item->pixmap(0) )
|
|
|
|
drag->setPixmap(*item->pixmap(0));
|
|
|
|
return drag;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::slotRMBPressed(TQListViewItem*, const TQPoint& p)
|
|
|
|
{
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
if(item == 0) return;
|
|
|
|
|
|
|
|
if(m_rmb) m_rmb->exec(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::newsubmenu()
|
|
|
|
{
|
|
|
|
TreeItem *parentItem = 0;
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
TQString caption = KInputDialog::getText( i18n( "New Submenu" ),
|
|
|
|
i18n( "Submenu name:" ), TQString::null, &ok, this );
|
|
|
|
|
|
|
|
if (!ok) return;
|
|
|
|
|
|
|
|
TQString file = caption;
|
|
|
|
file.replace('/', '-');
|
|
|
|
|
|
|
|
file = createDirectoryFile(file, &m_newDirectoryList); // Create
|
|
|
|
|
|
|
|
// get destination folder
|
|
|
|
TQString folder;
|
|
|
|
|
|
|
|
if(!item)
|
|
|
|
{
|
|
|
|
parentItem = 0;
|
|
|
|
folder = TQString::null;
|
|
|
|
}
|
|
|
|
else if(item->isDirectory())
|
|
|
|
{
|
|
|
|
parentItem = item;
|
|
|
|
item = 0;
|
|
|
|
folder = parentItem->directory();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parentItem = static_cast<TreeItem*>(item->parent());
|
|
|
|
folder = parentItem ? parentItem->directory() : TQString::null;
|
|
|
|
}
|
|
|
|
|
|
|
|
MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
|
|
|
|
MenuFolderInfo *folderInfo = new MenuFolderInfo();
|
|
|
|
folderInfo->caption = parentFolderInfo->uniqueMenuCaption(caption);
|
|
|
|
folderInfo->id = m_menuFile->uniqueMenuName(folder, caption, parentFolderInfo->existingMenuIds());
|
|
|
|
folderInfo->directoryFile = file;
|
|
|
|
folderInfo->icon = "package";
|
|
|
|
folderInfo->hidden = false;
|
|
|
|
folderInfo->setDirty();
|
|
|
|
|
|
|
|
KDesktopFile *df = new KDesktopFile(file);
|
|
|
|
df->writeEntry("Name", folderInfo->caption);
|
|
|
|
df->writeEntry("Icon", folderInfo->icon);
|
|
|
|
df->sync();
|
|
|
|
delete df;
|
|
|
|
// Add file to menu
|
|
|
|
// m_menuFile->addMenu(folder + folderInfo->id, file);
|
|
|
|
m_menuFile->pushAction(MenuFile::ADD_MENU, folder + folderInfo->id, file);
|
|
|
|
|
|
|
|
folderInfo->fullId = parentFolderInfo->fullId + folderInfo->id;
|
|
|
|
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
// update fileInfo data
|
|
|
|
parentFolderInfo->add(folderInfo);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, item, folderInfo, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
|
|
|
|
setLayoutDirty(parentItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::newitem()
|
|
|
|
{
|
|
|
|
TreeItem *parentItem = 0;
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
TQString caption = KInputDialog::getText( i18n( "New Item" ),
|
|
|
|
i18n( "Item name:" ), TQString::null, &ok, this );
|
|
|
|
|
|
|
|
if (!ok) return;
|
|
|
|
|
|
|
|
TQString menuId;
|
|
|
|
TQString file = caption;
|
|
|
|
file.replace('/', '-');
|
|
|
|
|
|
|
|
file = createDesktopFile(file, &menuId, &m_newMenuIds); // Create
|
|
|
|
|
|
|
|
KDesktopFile *df = new KDesktopFile(file);
|
|
|
|
df->writeEntry("Name", caption);
|
|
|
|
df->writeEntry("Type", "Application");
|
|
|
|
|
|
|
|
// get destination folder
|
|
|
|
TQString folder;
|
|
|
|
|
|
|
|
if(!item)
|
|
|
|
{
|
|
|
|
parentItem = 0;
|
|
|
|
folder = TQString::null;
|
|
|
|
}
|
|
|
|
else if(item->isDirectory())
|
|
|
|
{
|
|
|
|
parentItem = item;
|
|
|
|
item = 0;
|
|
|
|
folder = parentItem->directory();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parentItem = static_cast<TreeItem*>(item->parent());
|
|
|
|
folder = parentItem ? parentItem->directory() : TQString::null;
|
|
|
|
}
|
|
|
|
|
|
|
|
MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
|
|
|
|
|
|
|
|
// Add file to menu
|
|
|
|
// m_menuFile->addEntry(folder, menuId);
|
|
|
|
m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
|
|
|
|
|
|
|
|
KService *s = new KService(df);
|
|
|
|
s->setMenuId(menuId);
|
|
|
|
|
|
|
|
MenuEntryInfo *entryInfo = new MenuEntryInfo(s, df);
|
|
|
|
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
// update fileInfo data
|
|
|
|
parentFolderInfo->add(entryInfo);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, item, entryInfo, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
|
|
|
|
setLayoutDirty(parentItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::newsep()
|
|
|
|
{
|
|
|
|
TreeItem *parentItem = 0;
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
|
|
|
|
if(!item)
|
|
|
|
{
|
|
|
|
parentItem = 0;
|
|
|
|
}
|
|
|
|
else if(item->isDirectory())
|
|
|
|
{
|
|
|
|
parentItem = item;
|
|
|
|
item = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parentItem = static_cast<TreeItem*>(item->parent());
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, item, m_separator, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
|
|
|
|
setLayoutDirty(parentItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::cut()
|
|
|
|
{
|
|
|
|
copy( true );
|
|
|
|
|
|
|
|
m_ac->action("edit_cut")->setEnabled(false);
|
|
|
|
m_ac->action("edit_copy")->setEnabled(false);
|
|
|
|
m_ac->action("delete")->setEnabled(false);
|
|
|
|
|
|
|
|
// Select new current item
|
|
|
|
setSelected( currentItem(), true );
|
|
|
|
// Switch the UI to show that item
|
|
|
|
itemSelected( selectedItem() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::copy()
|
|
|
|
{
|
|
|
|
copy( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::copy( bool cutting )
|
|
|
|
{
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
|
|
|
|
// nil selected? -> nil to copy
|
|
|
|
if (item == 0) return;
|
|
|
|
|
|
|
|
if (cutting)
|
|
|
|
setLayoutDirty((TreeItem*)item->parent());
|
|
|
|
|
|
|
|
// clean up old stuff
|
|
|
|
cleanupClipboard();
|
|
|
|
|
|
|
|
// is item a folder or a file?
|
|
|
|
if(item->isDirectory())
|
|
|
|
{
|
|
|
|
TQString folder = item->directory();
|
|
|
|
if (cutting)
|
|
|
|
{
|
|
|
|
// Place in clipboard
|
|
|
|
m_clipboard = MOVE_FOLDER;
|
|
|
|
m_clipboardFolderInfo = item->folderInfo();
|
|
|
|
|
|
|
|
del(item, false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Place in clipboard
|
|
|
|
m_clipboard = COPY_FOLDER;
|
|
|
|
m_clipboardFolderInfo = item->folderInfo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (item->isEntry())
|
|
|
|
{
|
|
|
|
if (cutting)
|
|
|
|
{
|
|
|
|
// Place in clipboard
|
|
|
|
m_clipboard = MOVE_FILE;
|
|
|
|
m_clipboardEntryInfo = item->entryInfo();
|
|
|
|
|
|
|
|
del(item, false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Place in clipboard
|
|
|
|
m_clipboard = COPY_FILE;
|
|
|
|
m_clipboardEntryInfo = item->entryInfo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Place in clipboard
|
|
|
|
m_clipboard = COPY_SEPARATOR;
|
|
|
|
if (cutting)
|
|
|
|
del(item, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ac->action("edit_paste")->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TreeView::paste()
|
|
|
|
{
|
|
|
|
TreeItem *parentItem = 0;
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
|
|
|
|
// nil selected? -> nil to paste to
|
|
|
|
if (item == 0) return;
|
|
|
|
|
|
|
|
// is there content in the clipboard?
|
|
|
|
if (!m_clipboard) return;
|
|
|
|
|
|
|
|
// get destination folder
|
|
|
|
TQString folder;
|
|
|
|
|
|
|
|
if(item->isDirectory())
|
|
|
|
{
|
|
|
|
parentItem = item;
|
|
|
|
item = 0;
|
|
|
|
folder = parentItem->directory();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parentItem = static_cast<TreeItem*>(item->parent());
|
|
|
|
folder = parentItem ? parentItem->directory() : TQString::null;
|
|
|
|
}
|
|
|
|
|
|
|
|
MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
|
|
|
|
int command = m_clipboard;
|
|
|
|
if ((command == COPY_FOLDER) || (command == MOVE_FOLDER))
|
|
|
|
{
|
|
|
|
MenuFolderInfo *folderInfo = m_clipboardFolderInfo;
|
|
|
|
if (command == COPY_FOLDER)
|
|
|
|
{
|
|
|
|
// Ugh.. this is hard :)
|
|
|
|
// * Create new .directory file
|
|
|
|
// Add
|
|
|
|
}
|
|
|
|
else if (command == MOVE_FOLDER)
|
|
|
|
{
|
|
|
|
// Move menu
|
|
|
|
TQString oldFolder = folderInfo->fullId;
|
|
|
|
TQString folderName = folderInfo->id;
|
|
|
|
TQString newFolder = m_menuFile->uniqueMenuName(folder, folderName, parentFolderInfo->existingMenuIds());
|
|
|
|
folderInfo->id = newFolder;
|
|
|
|
|
|
|
|
// Add file to menu
|
|
|
|
// m_menuFile->moveMenu(oldFolder, folder + newFolder);
|
|
|
|
m_menuFile->pushAction(MenuFile::MOVE_MENU, oldFolder, folder + newFolder);
|
|
|
|
|
|
|
|
// Make sure caption is unique
|
|
|
|
TQString newCaption = parentFolderInfo->uniqueMenuCaption(folderInfo->caption);
|
|
|
|
if (newCaption != folderInfo->caption)
|
|
|
|
{
|
|
|
|
folderInfo->setCaption(newCaption);
|
|
|
|
}
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
// update fileInfo data
|
|
|
|
folderInfo->fullId = parentFolderInfo->fullId + folderInfo->id;
|
|
|
|
folderInfo->setInUse(true);
|
|
|
|
parentFolderInfo->add(folderInfo);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, item, folderInfo);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_clipboard = COPY_FOLDER; // Next one copies.
|
|
|
|
}
|
|
|
|
else if ((command == COPY_FILE) || (command == MOVE_FILE))
|
|
|
|
{
|
|
|
|
MenuEntryInfo *entryInfo = m_clipboardEntryInfo;
|
|
|
|
TQString menuId;
|
|
|
|
|
|
|
|
if (command == COPY_FILE)
|
|
|
|
{
|
|
|
|
// Need to copy file and then add it
|
|
|
|
KDesktopFile *df = copyDesktopFile(entryInfo, &menuId, &m_newMenuIds); // Duplicate
|
|
|
|
|
|
|
|
KService *s = new KService(df);
|
|
|
|
s->setMenuId(menuId);
|
|
|
|
entryInfo = new MenuEntryInfo(s, df);
|
|
|
|
|
|
|
|
TQString oldCaption = entryInfo->caption;
|
|
|
|
TQString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
|
|
|
|
entryInfo->setCaption(newCaption);
|
|
|
|
}
|
|
|
|
else if (command == MOVE_FILE)
|
|
|
|
{
|
|
|
|
menuId = entryInfo->menuId();
|
|
|
|
m_clipboard = COPY_FILE; // Next one copies.
|
|
|
|
|
|
|
|
TQString oldCaption = entryInfo->caption;
|
|
|
|
TQString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption);
|
|
|
|
entryInfo->setCaption(newCaption);
|
|
|
|
entryInfo->setInUse(true);
|
|
|
|
}
|
|
|
|
// Add file to menu
|
|
|
|
// m_menuFile->addEntry(folder, menuId);
|
|
|
|
m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
|
|
|
|
|
|
|
|
// create the TreeItem
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
// update fileInfo data
|
|
|
|
parentFolderInfo->add(entryInfo);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, item, entryInfo, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// create separator
|
|
|
|
if(parentItem)
|
|
|
|
parentItem->setOpen(true);
|
|
|
|
|
|
|
|
TreeItem *newItem = createTreeItem(parentItem, item, m_separator, true);
|
|
|
|
|
|
|
|
setSelected ( newItem, true);
|
|
|
|
itemSelected( newItem);
|
|
|
|
}
|
|
|
|
setLayoutDirty(parentItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::del()
|
|
|
|
{
|
|
|
|
TreeItem *item = (TreeItem*)selectedItem();
|
|
|
|
|
|
|
|
// nil selected? -> nil to delete
|
|
|
|
if (item == 0) return;
|
|
|
|
|
|
|
|
del(item, true);
|
|
|
|
|
|
|
|
m_ac->action("edit_cut")->setEnabled(false);
|
|
|
|
m_ac->action("edit_copy")->setEnabled(false);
|
|
|
|
m_ac->action("delete")->setEnabled(false);
|
|
|
|
// Select new current item
|
|
|
|
setSelected( currentItem(), true );
|
|
|
|
// Switch the UI to show that item
|
|
|
|
itemSelected( selectedItem() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::del(TreeItem *item, bool deleteInfo)
|
|
|
|
{
|
|
|
|
TreeItem *parentItem = static_cast<TreeItem*>(item->parent());
|
|
|
|
// is file a .directory or a .desktop file
|
|
|
|
if(item->isDirectory())
|
|
|
|
{
|
|
|
|
MenuFolderInfo *folderInfo = item->folderInfo();
|
|
|
|
|
|
|
|
// Remove MenuFolderInfo
|
|
|
|
MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
|
|
|
|
parentFolderInfo->take(folderInfo);
|
|
|
|
folderInfo->setInUse(false);
|
|
|
|
|
|
|
|
if (m_clipboard == COPY_FOLDER && (m_clipboardFolderInfo == folderInfo))
|
|
|
|
{
|
|
|
|
// Copy + Del == Cut
|
|
|
|
m_clipboard = MOVE_FOLDER; // Clipboard now owns folderInfo
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (folderInfo->takeRecursive(m_clipboardFolderInfo))
|
|
|
|
m_clipboard = MOVE_FOLDER; // Clipboard now owns m_clipboardFolderInfo
|
|
|
|
|
|
|
|
if (deleteInfo)
|
|
|
|
delete folderInfo; // Delete folderInfo
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove from menu
|
|
|
|
// m_menuFile->removeMenu(item->directory());
|
|
|
|
m_menuFile->pushAction(MenuFile::REMOVE_MENU, item->directory(), TQString::null);
|
|
|
|
|
|
|
|
// Remove tree item
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
else if (item->isEntry())
|
|
|
|
{
|
|
|
|
MenuEntryInfo *entryInfo = item->entryInfo();
|
|
|
|
TQString menuId = entryInfo->menuId();
|
|
|
|
|
|
|
|
// Remove MenuFolderInfo
|
|
|
|
MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
|
|
|
|
parentFolderInfo->take(entryInfo);
|
|
|
|
entryInfo->setInUse(false);
|
|
|
|
|
|
|
|
if (m_clipboard == COPY_FILE && (m_clipboardEntryInfo == entryInfo))
|
|
|
|
{
|
|
|
|
// Copy + Del == Cut
|
|
|
|
m_clipboard = MOVE_FILE; // Clipboard now owns entryInfo
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (deleteInfo)
|
|
|
|
delete entryInfo; // Delete entryInfo
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove from menu
|
|
|
|
TQString folder = parentItem ? parentItem->directory() : TQString::null;
|
|
|
|
// m_menuFile->removeEntry(folder, menuId);
|
|
|
|
m_menuFile->pushAction(MenuFile::REMOVE_ENTRY, folder, menuId);
|
|
|
|
|
|
|
|
// Remove tree item
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Remove separator
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
setLayoutDirty(parentItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::cleanupClipboard() {
|
|
|
|
if (m_clipboard == MOVE_FOLDER)
|
|
|
|
delete m_clipboardFolderInfo;
|
|
|
|
m_clipboardFolderInfo = 0;
|
|
|
|
|
|
|
|
if (m_clipboard == MOVE_FILE)
|
|
|
|
delete m_clipboardEntryInfo;
|
|
|
|
m_clipboardEntryInfo = 0;
|
|
|
|
|
|
|
|
m_clipboard = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static TQStringList extractLayout(TreeItem *item)
|
|
|
|
{
|
|
|
|
bool firstFolder = true;
|
|
|
|
bool firstEntry = true;
|
|
|
|
TQStringList layout;
|
|
|
|
for(;item; item = static_cast<TreeItem*>(item->nextSibling()))
|
|
|
|
{
|
|
|
|
if (item->isDirectory())
|
|
|
|
{
|
|
|
|
if (firstFolder)
|
|
|
|
{
|
|
|
|
firstFolder = false;
|
|
|
|
layout << ":M"; // Add new folders here...
|
|
|
|
}
|
|
|
|
layout << (item->folderInfo()->id);
|
|
|
|
}
|
|
|
|
else if (item->isEntry())
|
|
|
|
{
|
|
|
|
if (firstEntry)
|
|
|
|
{
|
|
|
|
firstEntry = false;
|
|
|
|
layout << ":F"; // Add new entries here...
|
|
|
|
}
|
|
|
|
layout << (item->entryInfo()->menuId());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
layout << ":S";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return layout;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList TreeItem::layout()
|
|
|
|
{
|
|
|
|
TQStringList layout = extractLayout(static_cast<TreeItem*>(firstChild()));
|
|
|
|
_layoutDirty = false;
|
|
|
|
return layout;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::saveLayout()
|
|
|
|
{
|
|
|
|
if (m_layoutDirty)
|
|
|
|
{
|
|
|
|
TQStringList layout = extractLayout(static_cast<TreeItem*>(firstChild()));
|
|
|
|
m_menuFile->setLayout(m_rootFolder->fullId, layout);
|
|
|
|
m_layoutDirty = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPtrList<TQListViewItem> lst;
|
|
|
|
TQListViewItemIterator it( this );
|
|
|
|
while ( it.current() ) {
|
|
|
|
TreeItem *item = static_cast<TreeItem*>(it.current());
|
|
|
|
if ( item->isLayoutDirty() )
|
|
|
|
{
|
|
|
|
m_menuFile->setLayout(item->folderInfo()->fullId, item->layout());
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TreeView::save()
|
|
|
|
{
|
|
|
|
saveLayout();
|
|
|
|
m_rootFolder->save(m_menuFile);
|
|
|
|
|
|
|
|
bool success = m_menuFile->performAllActions();
|
|
|
|
|
|
|
|
m_newMenuIds.clear();
|
|
|
|
m_newDirectoryList.clear();
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
KService::rebuildKSycoca(this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
KMessageBox::sorry(this, "<qt>"+i18n("Menu changes could not be saved because of the following problem:")+"<br><br>"+
|
|
|
|
m_menuFile->error()+"</qt>");
|
|
|
|
}
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::setLayoutDirty(TreeItem *parentItem)
|
|
|
|
{
|
|
|
|
if (parentItem)
|
|
|
|
parentItem->setLayoutDirty();
|
|
|
|
else
|
|
|
|
m_layoutDirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TreeView::isLayoutDirty()
|
|
|
|
{
|
|
|
|
TQPtrList<TQListViewItem> lst;
|
|
|
|
TQListViewItemIterator it( this );
|
|
|
|
while ( it.current() ) {
|
|
|
|
if ( static_cast<TreeItem*>(it.current())->isLayoutDirty() )
|
|
|
|
return true;
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TreeView::dirty()
|
|
|
|
{
|
|
|
|
return m_layoutDirty || m_rootFolder->hasDirt() || m_menuFile->dirty() || isLayoutDirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TreeView::findServiceShortcut(const KShortcut&cut, KService::Ptr &service)
|
|
|
|
{
|
|
|
|
service = m_rootFolder->findServiceShortcut(cut);
|
|
|
|
}
|
|
|
|
|