summaryrefslogtreecommitdiff
path: root/noncore/settings/tabmanager/tabmanager.cpp
authorllornkcor <llornkcor>2002-05-06 17:45:44 (UTC)
committer llornkcor <llornkcor>2002-05-06 17:45:44 (UTC)
commitd49663597393e1b9e63041964a080069e4b6a664 (patch) (side-by-side diff)
treeba788e8123b5e98d80ab2eea4012f31119968aa8 /noncore/settings/tabmanager/tabmanager.cpp
parent4a5885f1dd1328432e3bd3ef7cb2efd9a336b78b (diff)
downloadopie-d49663597393e1b9e63041964a080069e4b6a664.zip
opie-d49663597393e1b9e63041964a080069e4b6a664.tar.gz
opie-d49663597393e1b9e63041964a080069e4b6a664.tar.bz2
initial
Diffstat (limited to 'noncore/settings/tabmanager/tabmanager.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/tabmanager/tabmanager.cpp473
1 files changed, 473 insertions, 0 deletions
diff --git a/noncore/settings/tabmanager/tabmanager.cpp b/noncore/settings/tabmanager/tabmanager.cpp
new file mode 100644
index 0000000..db65d26
--- a/dev/null
+++ b/noncore/settings/tabmanager/tabmanager.cpp
@@ -0,0 +1,473 @@
+/*
+
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2002 Benjamin Meyer <meyerb@sharpsec.com>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library 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
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#include "tabmanager.h"
+#include "app.h"
+#include "tabapplnk.h"
+
+#include <qpe/applnk.h>
+#include <qpe/qpeapplication.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qlistview.h>
+#include <qheader.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qmessagebox.h>
+#include <stdlib.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#define HOME_APP_DIR QPEApplication::qpeDir()+"/apps" // <-- made this a little more flexible
+#define HOME_APP_INSTALL_DIR "/usr/lib/ipkg/info"
+#define NEW_FOLDER "EmptyTab"
+#define NEW_APPLICATION "NewApp"
+#define APPLICATION_EXTENSION ".desktop"
+#define APPLICATION_EXTENSION_LENGTH 8
+
+/**
+ * Constructor. Sets up signals. Performs initial scan of applications
+ * and tabs
+ */
+TabManager::TabManager( QWidget* parent, const char* name):TabManagerBase(parent, name), changed(false){
+ rescanFolder(HOME_APP_DIR);
+
+ // Connect the signals and slots
+ connect(tabList, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(editItem(QListViewItem*)));
+ (tabList->header())->hide();
+ connect(tabList, SIGNAL(moveItem(QListViewItem *, QListViewItem *)), this, SLOT(moveApplication(QListViewItem *, QListViewItem *)));
+}
+
+/**
+ * If anything in the tab's have been changed then update the system or alert
+ * the user.
+ */
+TabManager::~TabManager(){
+ if(changed){
+ //QMessageBox::critical(this, "Message", "Please restart Qtopia to see all new changes.",QString("Ok") );
+ //filename = fn;
+ QCopEnvelope e("QPE/System", "linkChanged(QString)");
+ //e << description << filename << mimetype;
+ QString link; //we'll just send an empty string
+ e << link;
+ }
+}
+
+/**
+ * Scans root directory for any tabs or applications. Will recursivly go down,
+ * but will not follow symlinks.
+ * @param directory - the directory to look in.
+ * @param parent - the parent to place any new tabs or apps into. If parent is
+ * NULL then the item is a tab and should be placed as a child of the window.
+ */
+void TabManager::rescanFolder(QString directory, QListViewItem* parent){
+ //qDebug(QString("rescanFolder: ") + directory.latin1());
+
+ QDir d;
+ d.setPath(directory);
+ // Show hidden files for .directories
+ d.setFilter( QDir::Files | QDir::Hidden | QDir::Dirs);
+
+ const QFileInfoList *list = d.entryInfoList();
+ QFileInfoListIterator it( *list ); // create list iterator
+ QFileInfo *fi; // pointer for traversing
+
+ while ( (fi=it.current()) ) { // for each file...
+ // If it is a dir and not .. or . then add it as a tab and go down.
+ if(fi->isDir()){
+ if(fi->fileName() != ".." && fi->fileName() != ".") {
+ QListViewItem* newItem;
+ if(!parent)
+ newItem = new QListViewItem(tabList, fi->fileName());
+ else
+ newItem = new QListViewItem(parent, fi->fileName());
+ itemList.insert(newItem, directory + "/" + fi->fileName() + "/.directory" );
+ rescanFolder(directory + "/" + fi->fileName(), newItem);
+ }
+ }
+ else{
+ // it is a file, if not a .directory add to parent.
+
+ // Change parents name and icon to reflect icon.
+ if(fi->fileName() == ".directory"){
+ AppLnk app(directory + "/" + fi->fileName());
+ if(parent){
+ parent->setPixmap(0,app.pixmap());
+ parent->setText(0, app.name());
+ }
+ }
+ else{
+ // Add any desktop files found.
+ QListViewItem* newItem;
+ if(directory != HOME_APP_DIR){
+ if(!parent)
+ newItem = new QListViewItem(tabList, fi->fileName());
+ else
+ newItem = new QListViewItem(parent, fi->fileName());
+ if(fi->fileName().right(APPLICATION_EXTENSION_LENGTH) == APPLICATION_EXTENSION){
+ AppLnk app(directory + "/" + fi->fileName());
+ newItem->setPixmap(0,app.pixmap());
+ newItem->setText(0, app.name());
+ itemList.insert(newItem, directory + "/" + fi->fileName());
+ }
+ }
+ }
+ }
+ ++it; // goto next list element
+ }
+}
+
+/**
+ * Create a new blank Tab.
+ * Create a physical folder with .directory file
+ * Create a item on the list
+ */
+void TabManager::newFolder(){
+ QDir r;
+ r.mkdir(QString(HOME_APP_DIR) + "/" + NEW_FOLDER);
+ system((QString("echo [Desktop Entry] | cat >> ") + HOME_APP_DIR + "/" + NEW_FOLDER "/.directory").latin1());
+ system((QString("echo Name=" NEW_FOLDER " | cat >> ") + HOME_APP_DIR + "/" + NEW_FOLDER "/.directory").latin1());
+
+ QString homeLocation = QString(HOME_APP_DIR) + "/" + NEW_FOLDER + "/.directory";
+ QListViewItem *newItem = new QListViewItem(tabList, NEW_FOLDER);
+ itemList.insert(newItem, homeLocation );
+
+ // We have changed something.
+ changed = true;
+}
+
+/**
+ * Create a new blank application
+ * Make sure a tab is selected
+ * create physical file
+ * fill file with default information (entry, name, type).
+ */
+void TabManager::newApplication(){
+ QListViewItem *item = tabList->currentItem();
+ if(!item || item->parent())
+ return;
+
+ QString parentDir = itemList[item].mid(0,itemList[item].length()-11);
+ QString homeLocation = parentDir + "/" NEW_APPLICATION APPLICATION_EXTENSION;
+ system((QString("echo [Desktop Entry] | cat >> ") + homeLocation).latin1());
+ system((QString("echo Name=" NEW_APPLICATION " | cat >> ") + homeLocation).latin1());
+ int slash = parentDir.findRev('/', -1);
+ QString folderName = parentDir.mid(slash+1, parentDir.length());
+
+ system((QString("echo Type=") + folderName + " | cat >> " + homeLocation).latin1());
+
+ // Insert into the tree
+ QListViewItem *newItem = new QListViewItem(item, NEW_APPLICATION);
+ itemList.insert(newItem, homeLocation );
+
+ // We have changed something.
+ changed = true;
+}
+
+/**
+ * Remove the item.
+ * Check if we can
+ * Prompt user
+ * Delete physical file (Dir, remove .dir, then dir. File, remove file)
+ * Remove from installer if need too.
+ */
+void TabManager::removeItem(){
+ // Make sure we can delete
+ QListViewItem *item = tabList->currentItem();
+ if(!item)
+ return;
+ if(item->childCount() > 0){
+ QMessageBox::critical(this, "Message", "Can't remove with applications\nstill in the group.",QString("Ok") );
+ return;
+ }
+
+ // Prompt.
+ int answer = QMessageBox::warning(this, "Message", "Are you sure you want to delete?","Yes", "Cancel", 0, 1 );
+ if (answer)
+ return;
+
+ bool removeSuccessfull = true;
+ QString location = itemList[item];
+ // Remove file (.directory in a Directory case)
+ if(!QFile::remove(location))
+ removeSuccessfull = false;
+
+ // Remove directory
+ if(item->parent() == NULL){
+ // Remove .directory file string
+ location = location.mid(0,location.length()-10);
+ QDir dir;
+ if(!dir.rmdir(location))
+ removeSuccessfull = false;
+ }
+
+ // If removing failed.
+ if(!removeSuccessfull){
+ qDebug((QString("removeItem: ") + location).latin1());
+ QMessageBox::critical(this, "Message", "Can't remove.",QString("Ok") );
+ return;
+ }
+
+ // Remove from the installer so it wont fail.
+ // Don't need to do this sense the current install uses rm -f so no error
+
+ // Remove from the gui list.
+ itemList.remove(item);
+ if(item->parent())
+ item->parent()->takeItem(item);
+ delete item;
+
+ // We have changed something.
+ changed = true;
+}
+
+/**
+ * Helper function. Edits the current item.
+ * calls editItem with the currently selected item.
+ */
+void TabManager::editCurrentItem(){
+ editItem(tabList->currentItem());
+}
+
+/**
+ * Edit the item that is passed in.
+ * Show application dialog and if anything changed
+ * @param item the item to edit.
+ */
+void TabManager::editItem( QListViewItem * item){
+ if(!item)
+ return;
+
+ TabAppLnk app(itemList[item]);
+ if(!app.isValid()){
+ qDebug(QString("editItem: Not a valid applnk file: ") + itemList[item].latin1());
+ return;
+ }
+
+ AppEdit application(this, "Application edit", true);
+ application.nameLineEdit->setText(app.name());
+ application.iconLineEdit->setText(app.pixmapString());
+ application.execLineEdit->setText(app.exec());
+ application.commentLineEdit->setText(app.comment());
+
+ if(item->parent() == NULL){
+ application.execLineEdit->setEnabled(false);
+ application.TextLabel3->setEnabled(false);
+ application.setCaption("Tab");
+ }
+
+ // Only do somthing if they hit OK
+ if(application.exec() == 0)
+ return;
+
+ // If nothing has changed exit (hmmm why did they hit ok?)
+ if(app.name() == application.nameLineEdit->text() &&
+ app.pixmapString() == application.iconLineEdit->text() &&
+ app.comment() == application.commentLineEdit->text() &&
+ app.exec() == application.execLineEdit->text())
+ return;
+
+ // Change the applnk file
+ QString oldName = app.name();
+ app.setName(application.nameLineEdit->text());
+ app.setIcon(application.iconLineEdit->text());
+ app.setComment(application.commentLineEdit->text());
+ app.setExec(application.execLineEdit->text());
+ if(!app.writeLink()){
+ QMessageBox::critical(this, "Message", "Can't save.",QString("Ok") );
+ return;
+ }
+
+ // Update the gui icon and name
+ item->setText(0,app.name());
+ item->setPixmap(0,app.pixmap());
+
+ // We have changed something.
+ changed = true;
+
+ // If we were dealing with a new folder or new application change
+ // the file names. Also change the item location in itemList
+ if(oldName == NEW_FOLDER){
+ QDir r;
+ QString oldName = itemList[item];
+ oldName = oldName.mid(0,oldName.length()-11);
+ QString newName = oldName.mid(0,oldName.length()-9);
+ newName = newName + "/" + app.name();
+ r.rename(oldName, newName);
+ itemList.remove(item);
+ itemList.insert(item, newName + "/.directory" );
+ }
+ else if(oldName == NEW_APPLICATION){
+ if(!item->parent())
+ return;
+ QString parentDir = itemList[item->parent()];
+ QDir r;
+ QString oldName = itemList[item];
+ QString newName = oldName.mid(0, parentDir.length()-10);
+ newName = newName + app.name() + APPLICATION_EXTENSION;
+ r.rename(oldName, newName);
+ itemList.remove(item);
+ itemList.insert(item, newName);
+ }
+}
+
+/**
+ * Move an application from one directory to another.
+ * Move in the gui, move in the applnk file, move in the installer.
+ * @param item the application to move
+ * @pearam newGroup the new parent of this application
+ */
+void TabManager::moveApplication(QListViewItem *item, QListViewItem *newGroup){
+ // Can we even move it?
+ if(!item || !item->parent() || newGroup->parent())
+ return;
+ if(item->parent() == newGroup)
+ return;
+
+ // Get the new folder, new file name,
+ QString newFolder = itemList[newGroup];
+ newFolder = newFolder.mid(0,newFolder.length()-11);
+ int slash = newFolder.findRev('/', -1);
+ QString folderName = newFolder.mid(slash+1, newFolder.length());
+
+ QString desktopFile = itemList[item];
+ slash = desktopFile.findRev('/', -1);
+ desktopFile = desktopFile.mid(slash, desktopFile.length());
+ newFolder = newFolder + desktopFile;
+
+ // Move file
+ QDir r;
+ if(!r.rename(itemList[item], newFolder)){
+ QMessageBox::critical(this, "Message", "Can't move application.",QString("Ok") );
+ return;
+ }
+ //qDebug((QString("moveApplication: ") + itemList[item]).latin1());
+ //qDebug((QString("moveApplication: ") + newFolder).latin1());
+
+ // Move in the gui
+ item->parent()->takeItem(item);
+ newGroup->insertItem(item);
+ newGroup->setOpen(true);
+
+ // Move file in the installer
+ QString installedAppFile;
+ if(findInstalledApplication(desktopFile, installedAppFile))
+ swapInstalledLocation(installedAppFile, desktopFile, newFolder);
+ else
+ qDebug("moveApplication: No installed app found for dekstop file");
+
+ // Move application type
+ AppLnk app(newFolder);
+ app.setType(folderName);
+ app.writeLink();
+
+ // Move in our internal list
+ itemList.remove(item);
+ itemList.insert(item, newFolder);
+
+ // We have changed something.
+ changed = true;
+}
+
+/**
+ * File the installed application that has this desktop file.
+ * Go through each file in HOME_APP_INSTALL_DIR and see if it contains desktop
+ * file
+ * @param desktopFile - the .desktop file to search for [foo.desktop]
+ * @param installedAppFile - location of the app install list
+ * @return true if successfull, false if file not found.
+ */
+bool TabManager::findInstalledApplication(QString desktopFile, QString &installedAppFile){
+
+ QDir d;
+ d.setPath(HOME_APP_INSTALL_DIR);
+ d.setFilter( QDir::Files );
+
+ const QFileInfoList *list = d.entryInfoList();
+ QFileInfoListIterator it( *list ); // create list iterator
+ QFileInfo *fi; // pointer for traversing
+
+ while ( (fi=it.current()) ) { // for each file...
+ QFile file(QString(HOME_APP_INSTALL_DIR) + "/" + fi->fileName());
+ if ( file.open(IO_ReadOnly) ) { // file opened successfully
+ QTextStream stream( &file ); // use a text stream
+ QString line;
+ while ( !stream.eof() ) { // until end of file...
+ line = stream.readLine(); // line of text excluding '\n'
+ if(line.contains(desktopFile)){
+ installedAppFile = QString(HOME_APP_INSTALL_DIR) + "/" + fi->fileName();
+ file.close();
+ return true;
+ }
+ }
+ file.close();
+ }
+ else
+ qDebug((QString("findInstalledApplication: Can't open file") + HOME_APP_INSTALL_DIR + "/" + fi->fileName()).latin1());
+ ++it; // goto next list element
+ }
+ return false;
+}
+
+/**
+ * Open a file and replace a file containing the old desktop file with the new.
+ * @param installedAppFile application installed list
+ * @param desktopFile old .desktop file
+ * @param newLocation new .desktop file
+ */
+void TabManager::swapInstalledLocation( QString installedAppFile, QString desktopFile, QString newLocation ){
+ QFile file(installedAppFile);
+ if ( !file.open(IO_ReadOnly) ){
+ qDebug(QString("swapInstalledLocation: Can't edit file: %1").arg(installedAppFile).latin1());
+ return;
+ }
+
+ QTextStream stream( &file ); // use a text stream
+ QString allLines;
+ while ( !stream.eof() ) { // until end of file...
+ QString line = stream.readLine(); // line of text excluding '\n'
+ if(line.contains(desktopFile))
+ allLines += newLocation;
+ else
+ allLines += line;
+ allLines += '\n';
+ }
+ file.close();
+
+ if ( !file.open(IO_ReadWrite) ){
+ qDebug(QString("swapInstalledLocation: Can't edit file: %1").arg(installedAppFile).latin1());
+ return;
+ }
+ QTextStream streamOut( &file );
+ streamOut << allLines;
+ file.close();
+}
+
+// tabmanager.cpp
+