/***************************************************************************
* Copyright ( C ) 2003 by S <EFBFBD> astien Laot *
* slaout @ linux62 . 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 <tqstring.h>
# include <tqstringlist.h>
# include <tqdir.h>
# include <tqfileinfo.h>
# include <tqdom.h>
# include <kglobalsettings.h>
# include <kmessagebox.h>
# include <klocale.h>
# include <kapplication.h>
# include <iostream>
# include "formatimporter.h"
# include "notecontent.h"
# include "notefactory.h"
# include "bnpview.h"
# include "basket.h"
# include "global.h"
# include "xmlwork.h"
# include "tools.h"
bool FormatImporter : : shouldImportBaskets ( )
{
// We should import if the application have not successfully loaded any basket...
if ( Global : : bnpView - > firstListViewItem ( ) )
return false ;
// ... And there is at least one folder in the save folder, with a ".basket" file inside that folder.
TQDir dir ( Global : : savesFolder ( ) , TQString ( ) , TQDir : : Name | TQDir : : IgnoreCase , TQDir : : Dirs | TQDir : : NoSymLinks ) ;
TQStringList list = dir . entryList ( ) ;
for ( TQStringList : : Iterator it = list . begin ( ) ; it ! = list . end ( ) ; + + it )
if ( * it ! = " . " & & * it ! = " .. " & & dir . exists ( Global : : savesFolder ( ) + * it + " /.basket " ) )
return true ;
return false ;
}
void FormatImporter : : copyFolder ( const TQString & folder , const TQString & newFolder )
{
copyFinished = false ;
KIO : : CopyJob * copyJob = KIO : : copyAs ( KURL ( folder ) , KURL ( newFolder ) , /*showProgressInfo=*/ false ) ;
connect ( copyJob , TQT_SIGNAL ( result ( KIO : : Job * ) ) , this , TQT_SLOT ( slotCopyingDone ( KIO : : Job * ) ) ) ;
while ( ! copyFinished )
kapp - > processEvents ( ) ;
}
void FormatImporter : : moveFolder ( const TQString & folder , const TQString & newFolder )
{
copyFinished = false ;
KIO : : CopyJob * copyJob = KIO : : moveAs ( KURL ( folder ) , KURL ( newFolder ) , /*showProgressInfo=*/ false ) ;
connect ( copyJob , TQT_SIGNAL ( result ( KIO : : Job * ) ) , this , TQT_SLOT ( slotCopyingDone ( KIO : : Job * ) ) ) ;
while ( ! copyFinished )
kapp - > processEvents ( ) ;
}
void FormatImporter : : slotCopyingDone ( KIO : : Job * )
{
// std::cout << "Copy finished of " + from.path() + " to " + to.path() << std::endl;
copyFinished = true ;
}
void FormatImporter : : importBaskets ( )
{
std : : cout < < " Import Baskets: Preparing... " < < std : : endl ;
// Some preliminary preparations (create the destination folders and the basket tree file):
TQDir dirPrep ;
dirPrep . mkdir ( Global : : savesFolder ( ) ) ;
dirPrep . mkdir ( Global : : basketsFolder ( ) ) ;
TQDomDocument document ( " basketTree " ) ;
TQDomElement root = document . createElement ( " basketTree " ) ;
document . appendChild ( root ) ;
// First up, establish a list of every baskets, ensure the old order (if any), and count them.
TQStringList baskets ;
// Read the 0.5.0 baskets order:
TQDomDocument * doc = XMLWork : : openFile ( " container " , Global : : savesFolder ( ) + " container.baskets " ) ;
if ( doc ! = 0 ) {
TQDomElement docElem = doc - > documentElement ( ) ;
TQDomElement basketsElem = XMLWork : : getElement ( docElem , " baskets " ) ;
TQDomNode n = basketsElem . firstChild ( ) ;
while ( ! n . isNull ( ) ) {
TQDomElement e = n . toElement ( ) ;
if ( ( ! e . isNull ( ) ) & & e . tagName ( ) = = " basket " )
baskets . append ( e . text ( ) ) ;
n = n . nextSibling ( ) ;
}
}
// Then load the baskets that weren't loaded (import < 0.5.0 ones):
TQDir dir ( Global : : savesFolder ( ) , TQString ( ) , TQDir : : Name | TQDir : : IgnoreCase , TQDir : : Dirs | TQDir : : NoSymLinks ) ;
TQStringList list = dir . entryList ( ) ;
if ( list . count ( ) > 2 ) // Pass "." and ".."
for ( TQStringList : : Iterator it = list . begin ( ) ; it ! = list . end ( ) ; + + it ) // For each folder
if ( * it ! = " . " & & * it ! = " .. " & & dir . exists ( Global : : savesFolder ( ) + * it + " /.basket " ) ) // If it can be a basket folder
if ( baskets . tqfind ( ( * it ) + " / " ) = = baskets . end ( ) & &
baskets . tqfind ( * it ) = = baskets . end ( ) ) // And if it is not already in the imported baskets list
baskets . append ( * it ) ;
std : : cout < < " Import Baskets: Found " < < baskets . count ( ) < < " baskets to import. " < < std : : endl ;
// Import every baskets:
int i = 0 ;
for ( TQStringList : : iterator it = baskets . begin ( ) ; it ! = baskets . end ( ) ; + + it ) {
+ + i ;
std : : cout < < " Import Baskets: Importing basket " < < i < < " of " < < baskets . count ( ) < < " ... " < < std : : endl ;
// Move the folder to the new repository (normal basket) or copy the folder (mirorred folder):
TQString folderName = * it ;
if ( folderName . startsWith ( " / " ) ) { // It was a folder mirror:
KMessageBox : : information ( 0 , i18n ( " <p>Folder mirroring is not possible anymore (see <a href='http://basket.kde.org/'>basket.kde.org</a> for more information).</p> "
" <p>The folder <b>%1</b> has been copied for the basket needs. You can either delete this folder or delete the basket, or use both. But remember that "
" modifying one will not modify the other anymore as they are now separate entities.</p> " ) . tqarg ( folderName ) , i18n ( " Folder Mirror Import " ) ,
" " , KMessageBox : : AllowLink ) ;
// Also modify folderName to be only the folder name and not the full path anymore:
TQString newFolderName = folderName ;
if ( newFolderName . endsWith ( " / " ) )
newFolderName = newFolderName . left ( newFolderName . length ( ) - 1 ) ;
newFolderName = newFolderName . mid ( newFolderName . tqfindRev ( ' / ' ) + 1 ) ;
newFolderName = Tools : : fileNameForNewFile ( newFolderName , Global : : basketsFolder ( ) ) ;
FormatImporter f ;
f . copyFolder ( folderName , Global : : basketsFolder ( ) + newFolderName ) ;
folderName = newFolderName ;
} else
dir . rename ( Global : : savesFolder ( ) + folderName , Global : : basketsFolder ( ) + folderName ) ; // Move the folder
// Import the basket structure file and get the properties (to add them in the tree basket-properties cache):
TQDomElement properties = importBasket ( folderName ) ;
// Add it to the XML document:
TQDomElement basketElement = document . createElement ( " basket " ) ;
root . appendChild ( basketElement ) ;
basketElement . setAttribute ( " folderName " , folderName ) ;
basketElement . appendChild ( properties ) ;
}
// Finalize (write to disk and delete now useless files):
std : : cout < < " Import Baskets: Finalizing... " < < std : : endl ;
TQFile file ( Global : : basketsFolder ( ) + " baskets.xml " ) ;
if ( file . open ( IO_WriteOnly ) ) {
TQTextStream stream ( & file ) ;
stream . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
TQString xml = document . toString ( ) ;
stream < < " <?xml version= \" 1.0 \" encoding= \" UTF-8 \" ?> \n " ;
stream < < xml ;
file . close ( ) ;
}
Tools : : deleteRecursively ( Global : : savesFolder ( ) + " .tmp " ) ;
dir . remove ( Global : : savesFolder ( ) + " container.baskets " ) ;
std : : cout < < " Import Baskets: Finished. " < < std : : endl ;
}
TQDomElement FormatImporter : : importBasket ( const TQString & folderName )
{
// Load the XML file:
TQDomDocument * document = XMLWork : : openFile ( " basket " , Global : : basketsFolder ( ) + folderName + " /.basket " ) ;
if ( ! document ) {
std : : cout < < " Import Baskets: Failed to read the basket file! " < < std : : endl ;
return TQDomElement ( ) ;
}
TQDomElement docElem = document - > documentElement ( ) ;
// Import properties (change <background color=""> to <appearance backgroundColor="">, and figure out if is a checklist or not):
TQDomElement properties = XMLWork : : getElement ( docElem , " properties " ) ;
TQDomElement background = XMLWork : : getElement ( properties , " background " ) ;
TQColor backgroundColor = TQColor ( background . attribute ( " color " ) ) ;
if ( backgroundColor . isValid ( ) & & ( backgroundColor ! = KGlobalSettings : : baseColor ( ) ) ) { // Use the default color if it was already that color:
TQDomElement appearance = document - > createElement ( " appearance " ) ;
appearance . setAttribute ( " backgroundColor " , backgroundColor . name ( ) ) ;
properties . appendChild ( appearance ) ;
}
TQDomElement disposition = document - > createElement ( " disposition " ) ;
disposition . setAttribute ( " mindMap " , " false " ) ;
disposition . setAttribute ( " columnCount " , " 1 " ) ;
disposition . setAttribute ( " free " , " false " ) ;
bool isCheckList = XMLWork : : trueOrFalse ( XMLWork : : getElementText ( properties , " showCheckBoxes " , false ) ) ;
// Insert all notes in a group (column): 1/ rename "items" to "group", 2/ add "notes" to root, 3/ move "group" into "notes"
TQDomElement column = XMLWork : : getElement ( docElem , " items " ) ;
column . setTagName ( " group " ) ;
TQDomElement notes = document - > createElement ( " notes " ) ;
notes . appendChild ( column ) ;
docElem . appendChild ( notes ) ;
// Import notes from older representations:
TQDomNode n = column . firstChild ( ) ;
while ( ! n . isNull ( ) ) {
TQDomElement e = n . toElement ( ) ;
if ( ! e . isNull ( ) ) {
e . setTagName ( " note " ) ;
TQDomElement content = XMLWork : : getElement ( e , " content " ) ;
// Add Check tag:
if ( isCheckList ) {
bool isChecked = XMLWork : : trueOrFalse ( e . attribute ( " checked " , " false " ) ) ;
XMLWork : : addElement ( * document , e , " tags " , ( isChecked ? " todo_done " : " todo_unchecked " ) ) ;
}
// Import annotations as folded groups:
TQDomElement tqparentE = column ;
TQString annotations = XMLWork : : getElementText ( e , " annotations " , " " ) ;
if ( ! annotations . isEmpty ( ) ) {
TQDomElement annotGroup = document - > createElement ( " group " ) ;
column . insertBefore ( annotGroup , e ) ;
annotGroup . setAttribute ( " folded " , " true " ) ;
annotGroup . appendChild ( e ) ;
tqparentE = annotGroup ;
// Create the text note and add it to the DOM tree:
TQDomElement annotNote = document - > createElement ( " note " ) ;
annotNote . setAttribute ( " type " , " text " ) ;
annotGroup . appendChild ( annotNote ) ;
TQString annotFileName = Tools : : fileNameForNewFile ( " annotations1.txt " , Basket : : fullPathForFolderName ( folderName ) ) ;
TQString annotFullPath = Basket : : fullPathForFolderName ( folderName ) + " / " + annotFileName ;
TQFile file ( annotFullPath ) ;
if ( file . open ( IO_WriteOnly ) ) {
TQTextStream stream ( & file ) ;
stream < < annotations ;
file . close ( ) ;
}
XMLWork : : addElement ( * document , annotNote , " content " , annotFileName ) ;
n = annotGroup ;
}
// Import Launchers from 0.3.x, 0.4.0 and 0.5.0-alphas:
TQString runCommand = e . attribute ( " runcommand " ) ; // Keep compatibility with 0.4.0 and 0.5.0-alphas versions
runCommand = XMLWork : : getElementText ( e , " action " , runCommand ) ; // Keep compatibility with 0.3.x versions
if ( ! runCommand . isEmpty ( ) ) { // An import should be done
// Prepare the launcher note:
TQString title = content . attribute ( " title " , " " ) ;
TQString icon = content . attribute ( " icon " , " " ) ;
if ( title . isEmpty ( ) ) title = runCommand ;
if ( icon . isEmpty ( ) ) icon = NoteFactory : : iconForCommand ( runCommand ) ;
// Import the launcher note:
// Adapted version of "TQString launcherName = NoteFactory::createNoteLauncherFile(runCommand, title, icon, this)":
TQString launcherContent = TQString (
" [Desktop Entry] \n "
" Exec=%1 \n "
" Name=%2 \n "
" Icon=%3 \n "
" Encoding=UTF-8 \n "
" Type=Application \n " ) . tqarg ( runCommand , title , icon . isEmpty ( ) ? TQString ( " exec " ) : icon ) ;
TQString launcherFileName = Tools : : fileNameForNewFile ( " launcher.desktop " , Global : : basketsFolder ( ) + folderName /*+ "/"*/ ) ;
TQString launcherFullPath = Global : : basketsFolder ( ) + folderName /*+ "/"*/ + launcherFileName ;
TQFile file ( launcherFullPath ) ;
if ( file . open ( IO_WriteOnly ) ) {
TQTextStream stream ( & file ) ;
stream . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
stream < < launcherContent ;
file . close ( ) ;
}
// Add the element to the DOM:
TQDomElement launcherElem = document - > createElement ( " note " ) ;
tqparentE . insertBefore ( launcherElem , e ) ;
launcherElem . setAttribute ( " type " , " launcher " ) ;
XMLWork : : addElement ( * document , launcherElem , " content " , launcherFileName ) ;
}
// Import unknown ns to 0.6.0:
if ( e . attribute ( " type " ) = = " unknow " )
e . setAttribute ( " type " , " unknown " ) ;
// Import links from version < 0.5.0:
if ( ! content . attribute ( " autotitle " ) . isEmpty ( ) & & content . attribute ( " autoTitle " ) . isEmpty ( ) )
content . setAttribute ( " autoTitle " , content . attribute ( " autotitle " ) ) ;
if ( ! content . attribute ( " autoicon " ) . isEmpty ( ) & & content . attribute ( " autoIcon " ) . isEmpty ( ) )
content . setAttribute ( " autoIcon " , content . attribute ( " autoicon " ) ) ;
}
n = n . nextSibling ( ) ;
}
// Save the resulting XML file:
TQFile file ( Global : : basketsFolder ( ) + folderName + " /.basket " ) ;
if ( file . open ( IO_WriteOnly ) ) {
TQTextStream stream ( & file ) ;
stream . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
// TQString xml = document->toString();
// stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
// stream << xml;
stream < < document - > toString ( ) ; // Document is ALREADY using UTF-8
file . close ( ) ;
} else
std : : cout < < " Import Baskets: Failed to save the basket file! " < < std : : endl ;
// Return the newly created properties (to put in the basket tree):
return properties ;
}
# include "formatimporter.moc"