[KLF Application][KLF Tools][KLF Backend][KLF Home]
KLatexFormula Project

src/klflibbrowser.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   file klflibbrowser.cpp
00003  *   This file is part of the KLatexFormula Project.
00004  *   Copyright (C) 2010 by Philippe Faist
00005  *   philippe.faist at bluewin.ch
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 /* $Id: klflibbrowser.cpp 573 2010-11-28 21:22:31Z philippe $ */
00023 
00024 #include <QDebug>
00025 #include <QFile>
00026 #include <QMenu>
00027 #include <QAction>
00028 #include <QEvent>
00029 #include <QKeyEvent>
00030 #include <QShortcut>
00031 #include <QMessageBox>
00032 #include <QSignalMapper>
00033 #include <QLineEdit>
00034 #include <QProgressDialog>
00035 #include <QPushButton>
00036 #include <QApplication>
00037 #include <QClipboard>
00038 #include <QDesktopServices>
00039 
00040 #include "klfconfig.h"
00041 #include <klfguiutil.h>
00042 #include "klflibbrowser_p.h"
00043 #include "klflibbrowser.h"
00044 #include <ui_klflibbrowser.h>
00045 #include "klfliblegacyengine.h"
00046 
00047 
00048 KLFLibBrowser::KLFLibBrowser(QWidget *parent)
00049   : QWidget(
00050 #if defined(Q_OS_WIN32)
00051             0 /* parent */
00052 #else
00053             parent /* 0 */
00054 #endif
00055             , Qt::Window)
00056 {
00057   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00058 
00059   u = new Ui::KLFLibBrowser;
00060   u->setupUi(this);
00061   u->tabResources->setContextMenuPolicy(Qt::CustomContextMenu);
00062 
00063   KLF_DEBUG_ASSIGN_REF_INSTANCE(u->searchBar, "libbrowser-searchbar") ;
00064   u->searchBar->registerShortcuts(this);
00065   // set found/not-found colors
00066   u->searchBar->setColorFound(klfconfig.LibraryBrowser.colorFound);
00067   u->searchBar->setColorNotFound(klfconfig.LibraryBrowser.colorNotFound);
00068 
00069   pResourceMenu = new QMenu(u->tabResources);
00070   // connect actions
00071   connect(u->aRename, SIGNAL(triggered()), this, SLOT(slotResourceRename()));
00072   connect(u->aRenameSubRes, SIGNAL(triggered()), this, SLOT(slotResourceRenameSubResource()));
00073   connect(u->aProperties, SIGNAL(triggered()), this, SLOT(slotResourceProperties()));
00074   connect(u->aNewSubRes, SIGNAL(triggered()), this, SLOT(slotResourceNewSubRes()));
00075   connect(u->aDelSubRes, SIGNAL(triggered()), this, SLOT(slotResourceDelSubRes()));
00076   connect(u->aSaveTo, SIGNAL(triggered()), this, SLOT(slotResourceSaveTo()));
00077   connect(u->aNew, SIGNAL(triggered()), this, SLOT(slotResourceNew()));
00078   connect(u->aOpen, SIGNAL(triggered()), this, SLOT(slotResourceOpen()));
00079   connect(u->aClose, SIGNAL(triggered()), this, SLOT(slotResourceClose()));
00080   // and add them to menu
00081   pResourceMenu->addAction((new KLFLibBrowserTabMenu(u->tabResources))->menuAction());
00082   pResourceMenu->addSeparator();
00083   pResourceMenu->addAction(u->aRename);
00084   pResourceMenu->addAction(u->aRenameSubRes);
00085   pResourceMenu->addAction(u->aProperties);
00086   pResourceMenu->addSeparator();
00087   pResourceMenu->addAction(u->aViewType);
00088   pResourceMenu->addSeparator();
00089   pResourceMenu->addAction(u->aNewSubRes);
00090   pResourceMenu->addAction(u->aOpenSubRes);
00091   pResourceMenu->addAction(u->aDelSubRes);
00092   pResourceMenu->addSeparator();
00093   pResourceMenu->addAction(u->aNew);
00094   pResourceMenu->addAction(u->aOpen);
00096   //  pResourceMenu->addAction(u->aSaveTo);
00097   pResourceMenu->addAction(u->aClose);
00098 
00099   slotRefreshResourceActionsEnabled();
00100 
00101   pTabCornerButton = new QPushButton(u->tabResources);
00102   pTabCornerButton->setMenu(pResourceMenu);
00103   u->tabResources->setCornerWidget(pTabCornerButton);
00104 
00105   connect(u->tabResources, SIGNAL(currentChanged(int)), this, SLOT(slotTabResourceShown(int)));
00106   connect(u->tabResources, SIGNAL(customContextMenuRequested(const QPoint&)),
00107           this, SLOT(slotShowTabContextMenu(const QPoint&)));
00108 
00109   // RESTORE
00110 
00111   QMenu * restoreMenu = new QMenu(this);
00112   connect(u->aRestoreWithStyle, SIGNAL(triggered()), this, SLOT(slotRestoreWithStyle()));
00113   connect(u->aRestoreLatexOnly, SIGNAL(triggered()), this, SLOT(slotRestoreLatexOnly()));
00114   restoreMenu->addAction(u->aRestoreWithStyle);
00115   restoreMenu->addAction(u->aRestoreLatexOnly);
00116   u->btnRestore->setMenu(restoreMenu);
00117 
00118   connect(u->btnRestore, SIGNAL(clicked()), this, SLOT(slotRestoreWithStyle()));
00119   connect(u->btnDelete, SIGNAL(clicked()), this, SLOT(slotDeleteSelected()));
00120   connect(u->aDelete, SIGNAL(triggered()), u->btnDelete, SLOT(animateClick()));
00121 
00122   // IMPORT/EXPORT
00123 
00124   pImportExportMenu = new QMenu(this);
00125   pImportExportMenu->addAction(u->aOpenAll);
00126   pImportExportMenu->addAction(u->aExport);
00127   pImportExportMenu->addAction(u->aExportSelection);
00128   u->btnImportExport->setMenu(pImportExportMenu);
00129 
00130   connect(u->aOpenAll, SIGNAL(triggered()), this, SLOT(slotOpenAll()));
00131   connect(u->aExport, SIGNAL(triggered()), this, SLOT(slotExport()));
00132   connect(u->aExportSelection, SIGNAL(triggered()), this, SLOT(slotExportSelection()));
00133   
00134 
00135   // CATEGORY/TAGS
00136 
00137   connect(u->wEntryEditor, SIGNAL(metaInfoChanged(const QMap<int,QVariant>&)),
00138           this, SLOT(slotMetaInfoChanged(const QMap<int,QVariant>&)));
00139 
00140   connect(u->wEntryEditor, SIGNAL(restoreStyle(const KLFStyle&)),
00141           this, SIGNAL(requestRestoreStyle(const KLFStyle&)));
00142 
00143   // OPEN / NEW BUTTONS IN WELCOME TAB
00144 
00145   connect(u->btnOpenRes, SIGNAL(clicked()), this, SLOT(slotResourceOpen()));
00146   connect(u->btnCreateRes, SIGNAL(clicked()), this, SLOT(slotResourceNew()));
00147 
00148   // SHORTCUTS
00149                       
00150   // cut/copy/paste
00151   (void)new QShortcut(QKeySequence::Delete, this, SLOT(slotDeleteSelected()));
00152   (void)new QShortcut(QKeySequence::Cut, this, SLOT(slotCut()));
00153   (void)new QShortcut(QKeySequence::Copy, this, SLOT(slotCopy()));
00154   (void)new QShortcut(QKeySequence::Paste, this, SLOT(slotPaste()));
00155 
00156   retranslateUi(false);
00157 
00158   // start with no entries selected
00159   slotEntriesSelected(QList<KLFLibEntry>());
00160 }
00161 
00162 void KLFLibBrowser::retranslateUi(bool alsoBaseUi)
00163 {
00164   if (alsoBaseUi)
00165     u->retranslateUi(this);
00166 
00167   u->wEntryEditor->retranslateUi(alsoBaseUi);
00168 
00169   pResourceMenu->setTitle(tr("Resource Actions", "[[menu title]]"));
00170   u->searchBar->setFocusOutText("  "+tr("Hit Ctrl-F, Ctrl-S or / to search within the current resource"));
00171   pTabCornerButton->setText(tr("Resource"));
00172 }
00173 
00174 
00175 KLFLibBrowser::~KLFLibBrowser()
00176 {
00177   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00178 
00179   int k;
00180   for (k = 0; k < pLibViews.size(); ++k) {
00181     KLFLibResourceEngine * engine = pLibViews[k]->resourceEngine();
00182     delete pLibViews[k];
00183     delete engine;
00184   }
00185 
00186   delete u;
00187 }
00188 
00189 
00190 bool KLFLibBrowser::eventFilter(QObject *obj, QEvent *ev)
00191 {
00192   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00193 
00194   if (obj->property("resourceTitleEditor").toBool() == true) {
00195     if (ev->type() == QEvent::FocusOut) {
00196       obj->deleteLater(); // if lost focus, cancel...
00197       // don't eat event
00198     }
00199     if (ev->type() == QEvent::KeyPress) {
00200       QKeyEvent *ke = (QKeyEvent*)ev;
00201       if (ke->key() == Qt::Key_Escape) {
00202         obj->deleteLater();
00203         return true;
00204       }
00205     }
00206   }
00207 
00208   if (ev->type() == QEvent::Hide &&
00209       obj->property("klf_libbrowser_pdlg_want_hideautodelete").toBool() == true) {
00210     // this object is a resource-operation progress dialog that was just hidden
00211     klfDbg( ": progress dialog was hidden, deleting." ) ;
00212     obj->deleteLater();
00213     return true;
00214     //    return false;    // continue with event handling
00215   }
00216 
00217   return QWidget::eventFilter(obj, ev);
00218 }
00219 
00220 int KLFLibBrowser::currentUrlIndex()
00221 {
00222   KLFLibBrowserViewContainer *viewc = curView();
00223   if (viewc == NULL)
00224     return -1;
00225   return pLibViews.indexOf(viewc);
00226 }
00227 
00228 QUrl KLFLibBrowser::currentUrl()
00229 {
00230   int i = currentUrlIndex();
00231   if (i < 0 || i >= pLibViews.size())
00232     return QUrl();
00233   return pLibViews[i]->url();
00234 }
00235 
00236 
00237 QList<QUrl> KLFLibBrowser::openUrls() const
00238 {
00239   QList<QUrl> urls;
00240   int k;
00241   for (k = 0; k < pLibViews.size(); ++k) {
00242     urls << pLibViews[k]->url();
00243   }
00244   return urls;
00245 }
00246 
00247 KLFLibResourceEngine * KLFLibBrowser::getOpenResource(const QUrl& url)
00248 {
00249   KLFLibBrowserViewContainer * viewc = findOpenUrl(url);
00250   if (viewc == NULL)
00251     return NULL;
00252   return viewc->resourceEngine();
00253 }
00254 
00255 KLFAbstractLibView * KLFLibBrowser::getView(const QUrl& url)
00256 {
00257   KLFLibBrowserViewContainer * viewc = findOpenUrl(url);
00258   if (viewc == NULL)
00259     return NULL;
00260   return viewc->view();
00261 }
00262 
00263 KLFAbstractLibView * KLFLibBrowser::getView(KLFLibResourceEngine *resource)
00264 {
00265   KLFLibBrowserViewContainer * viewc = findOpenResource(resource);
00266   if (viewc == NULL)
00267     return NULL;
00268   return viewc->view();
00269 }
00270 
00271 
00272 
00273 QVariantMap KLFLibBrowser::saveGuiState()
00274 {
00275   QVariantMap v;
00276   // first save the list of open URLs
00277   QList<QUrl> myurllist = openUrls();
00278   QUrl currenturl = currentUrl();
00279   QList<QVariant> urllist; // will hold URL's as QUrl's
00280   QList<QVariant> viewstatelist; // will hold variantMap's
00281   QList<QVariant> resroleflagslist; // will hold quint32's
00282 
00283   int k;
00284   for (k = 0; k < myurllist.size(); ++k) {
00285     KLFLibBrowserViewContainer *viewc = findOpenUrl(myurllist[k]);
00286     if (viewc == NULL) {
00287       qWarning()<<"Should NOT HAPPEN! viewc is NULL in KLFLibBrowser::saveGuiState()! URL-List=\n"
00288                 <<myurllist;
00289       continue;
00290     }
00291     QVariantMap viewState = viewc->saveGuiState();
00292     urllist << QVariant::fromValue<QUrl>(myurllist[k]);
00293     viewstatelist << QVariant::fromValue<QVariantMap>(viewState);
00294     resroleflagslist << QVariant::fromValue<quint32>(viewc->resourceRoleFlags());
00295   }
00296   v["UrlList"] = QVariant::fromValue<QVariantList>(urllist);
00297   v["ViewStateList"] = QVariant::fromValue<QVariantList>(viewstatelist);
00298   v["ResourceRoleFlagsList"] = QVariant::fromValue<QVariantList>(resroleflagslist);
00299   v["CurrentUrl"] = QVariant::fromValue<QUrl>(currenturl);
00300   v["WidgetSize"] = QVariant::fromValue<QSize>(size());
00301   return v;
00302 }
00303 void KLFLibBrowser::loadGuiState(const QVariantMap& v, bool openURLs)
00304 {
00305   QUrl currenturl = v["CurrentUrl"].toUrl();
00306   QList<QVariant> urllist = v["UrlList"].toList();
00307   QList<QVariant> viewstatelist = v["ViewStateList"].toList();
00308   QList<QVariant> resroleflagslist = v["ResourceRoleFlagsList"].toList();
00309   QSize widgetsize = v["WidgetSize"].value<QSize>();
00310   int k;
00311   for (k = 0; k < urllist.size(); ++k) {
00312     QUrl url = urllist[k].toUrl();
00313     quint32 flags = resroleflagslist[k].value<quint32>();
00314     klfDbg( "LibBrowser::loadGuiState: Opening url "<<url<<" with flags="<<flags ) ;
00315     QVariantMap viewState = viewstatelist[k].toMap();
00316     // don't open new URLs if openURLs is false
00317     if ( !openURLs && findOpenUrl(url) == NULL )
00318       continue;
00319     // open this URL
00320     bool res = openResourceFromGuiState(url, viewState);
00321     // ignore flags, in case we eg. change library file, don't keep the old ones uncloseable
00322     // updateResourceRoleFlags(..., flags);
00323     if ( ! res ) {
00324       qWarning()<<"KLFLibBrowser::loadGuiState: Can't open resource "<<url<<"! (flags="
00325                 <<flags<<")";
00326       continue;
00327     }
00328   }
00329   klfDbg( "Almost finished loading gui state." ) ;
00330   KLFLibBrowserViewContainer *curviewc = findOpenUrl(currenturl);
00331   if (curviewc != NULL)
00332     u->tabResources->setCurrentWidget(curviewc);
00333   klfDbg( "Loaded GUI state." ) ;
00334 
00335   if (widgetsize.width() > 0 && widgetsize.height() > 0)
00336     resize(widgetsize);
00337 }
00338 
00339 
00340 
00341 // static
00342 QString KLFLibBrowser::displayTitle(KLFLibResourceEngine *resource)
00343 {
00344   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00345 
00346   KLF_ASSERT_NOT_NULL( resource, "Resource is NULL!", return QString() ) ;
00347 
00348   QString basestr;
00349   if (resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources) {
00350     QString subresourcetitle = resource->defaultSubResource();
00351     if (resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps)
00352       subresourcetitle
00353         = resource->subResourceProperty(resource->defaultSubResource(),
00354                                         KLFLibResourceEngine::SubResPropTitle).toString();
00355     basestr = QString("%1 - %2").arg(resource->title(), subresourcetitle);
00356   } else {
00357     basestr = resource->title();
00358   }
00359   if (!resource->canModifyData(KLFLibResourceEngine::AllActionsData)) {
00360     basestr = "# "+basestr;
00361   }
00362   return basestr;
00363 }
00364 
00365 
00366 KLFLibBrowserViewContainer * KLFLibBrowser::findOpenUrl(const QUrl& url)
00367 {
00368   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00369 
00370   klfDbg( "\turl is "<<url ) ;
00371   int k;
00372   for (k = 0; k < pLibViews.size(); ++k) {
00373     klfDbg("\t\ttest lib view #"<<k) ;
00374     klfDbg("\t\turl="<<pLibViews[k]->url() ) ;
00375     // allow: * urls to be equal
00376     //        * this resource's URL to be less specific (shows more) than what we're searching for
00377     uint fl = pLibViews[k]->view()->compareUrlTo(url, KlfUrlCompareEqual|KlfUrlCompareLessSpecific);
00378     if (fl & KlfUrlCompareEqual ||
00379         fl & KlfUrlCompareLessSpecific) {
00380       klfDbg( ": Found!" ) ;
00381       return pLibViews[k];
00382     }
00383   }
00384   return NULL;
00385 }
00386 
00387 KLFLibBrowserViewContainer * KLFLibBrowser::findOpenResource(KLFLibResourceEngine *resource)
00388 {
00389   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00390 
00391   int k;
00392   for (k = 0; k < pLibViews.size(); ++k)
00393     if (pLibViews[k]->resourceEngine() == resource)
00394       return pLibViews[k];
00395   return NULL;
00396 }
00397 
00398 KLFLibBrowserViewContainer * KLFLibBrowser::curView()
00399 {
00400   return qobject_cast<KLFLibBrowserViewContainer*>(u->tabResources->currentWidget());
00401 }
00402 KLFAbstractLibView * KLFLibBrowser::curLibView()
00403 {
00404   KLFLibBrowserViewContainer *v = curView();
00405   if (v == NULL)
00406     return NULL;
00407   return v->view();
00408 }
00409 KLFLibBrowserViewContainer * KLFLibBrowser::viewForTabIndex(int tab)
00410 {
00411   return qobject_cast<KLFLibBrowserViewContainer*>(u->tabResources->widget(tab));
00412 }
00413 QList<KLFLibBrowserViewContainer*> KLFLibBrowser::findByRoleFlags(uint testflags, uint mask)
00414 {
00415   klfDbg("Looking for flags "<<klfFmtCC("%#010x", testflags)<<" with mask "<<klfFmtCC("%#010x", mask)) ;
00416   QList<KLFLibBrowserViewContainer *> list;
00417   int k;
00418   for (k = 0; k < pLibViews.size(); ++k) {
00419     if ((pLibViews[k]->resourceRoleFlags() & mask) == testflags) {
00420       klfDbg("Adding #"<<k<<": "<<pLibViews[k]<<", url="<<pLibViews[k]->url()) ;
00421       list << pLibViews[k];
00422     }
00423   }
00424   return list;
00425 }
00426 
00427 
00428 
00429 bool KLFLibBrowser::openResource(const QString& url, uint resourceRoleFlags,
00430                                  const QString& viewTypeIdentifier)
00431 {
00432   KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME+QString("(QString,uint,QString)")) ;
00433   return openResource(QUrl(url), resourceRoleFlags, viewTypeIdentifier);
00434 }
00435 
00436 bool KLFLibBrowser::openResource(const QUrl& url, uint resourceRoleFlags,
00437                                  const QString& viewTypeIdentifier)
00438 {
00439   KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME+"(QUrl,uint,QString)") ;
00440   klfDbg( " url="<<url.toString()<<"; resroleflags="<<resourceRoleFlags
00441           <<"; vtypeidentifier="<<viewTypeIdentifier ) ;
00442 
00443   KLFLibBrowserViewContainer * openview = findOpenUrl(url);
00444   if (openview != NULL) {
00445     qDebug("KLFLibBrowser::openResource(%s,%u): This resource is already open.",
00446            qPrintable(url.toString()), resourceRoleFlags);
00447     if ((resourceRoleFlags & OpenNoRaise) == 0)
00448       u->tabResources->setCurrentWidget(openview);
00449     updateResourceRoleFlags(openview, resourceRoleFlags);
00450     return true;
00451   }
00452 
00453   KLFLibEngineFactory * factory = KLFLibEngineFactory::findFactoryFor(url.scheme());
00454   if ( factory == NULL ) {
00455     qWarning()<<KLF_FUNC_NAME<<": failed to find appropriate factory for url="<<url.toString()<<"!";
00456     return false;
00457   }
00458   KLFLibResourceEngine * resource = factory->openResource(url, this);
00459   if ( resource == NULL ) {
00460     qWarning()<<KLF_FUNC_NAME<<": factory failed to open resource "<<url.toString()<<"!";
00461     return false;
00462   }
00463 
00464   // go on opening resource with our sister function
00465   return openResource(resource, resourceRoleFlags, viewTypeIdentifier);
00466 }
00467 bool KLFLibBrowser::openResource(KLFLibResourceEngine *resource, uint resourceRoleFlags,
00468                                  const QString& viewTypeIdentifier)
00469 {
00470   KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME+"(KLFLibResourceEngine*,uint,QString)") ;
00471   klfDbg( "\topening resource url="
00472           <<resource->url(KLFLibResourceEngine::WantUrlDefaultSubResource).toString() ) ;
00473 
00474   //  KLFPleaseWaitPopup label(tr("Loading resource, please wait..."), this);
00475 
00476   KLF_ASSERT_NOT_NULL(resource,
00477                       "resource pointer is NULL! (flags="<<resourceRoleFlags<<",vti="<<viewTypeIdentifier<<")",
00478                       return false );
00479 
00480   KLFLibBrowserViewContainer * openview = findOpenResource(resource);
00481   if (openview != NULL) {
00482     qDebug("KLFLibBrowser::openResource(%p,%u): This resource is already open.",
00483            resource, resourceRoleFlags);
00484     if ((resourceRoleFlags & OpenNoRaise) == 0)
00485       u->tabResources->setCurrentWidget(openview);
00486     updateResourceRoleFlags(openview, resourceRoleFlags);
00487     return true;
00488   }
00489 
00490   resource->setParent(this);
00491 
00492   klfDbgT(": created resource. about to create view container.") ;
00493 
00494   // now create appropriate view for this resource
00495   KLFLibBrowserViewContainer *viewc = new KLFLibBrowserViewContainer(resource, u->tabResources);
00496 
00497   klfDbgT(": adding tab page....") ;
00498 
00499   int i = u->tabResources->addTab(viewc, displayTitle(resource));
00500   if ((resourceRoleFlags & OpenNoRaise) == 0)
00501     u->tabResources->setCurrentWidget(viewc);
00502   u->tabResources
00503     ->refreshTabReadOnly(i, !resource->canModifyData(KLFLibResourceEngine::AllActionsData));
00504   pLibViews.append(viewc);
00505   setStyleSheet(styleSheet());
00506   updateResourceRoleFlags(viewc, resourceRoleFlags);
00507 
00508 
00509   // get informed about selection changes
00510   connect(viewc, SIGNAL(entriesSelected(const KLFLibEntryList& )),
00511           this, SLOT(slotEntriesSelected(const KLFLibEntryList& )));
00512   // and of new category suggestions
00513   connect(viewc, SIGNAL(moreCategorySuggestions(const QStringList&)),
00514           this, SLOT(slotAddCategorySuggestions(const QStringList&)));
00515 
00516   connect(viewc, SIGNAL(requestRestore(const KLFLibEntry&, uint)),
00517           this, SIGNAL(requestRestore(const KLFLibEntry&, uint)));
00518   connect(viewc, SIGNAL(requestRestoreStyle(const KLFStyle&)),
00519           this, SIGNAL(requestRestoreStyle(const KLFStyle&)));
00520 
00521   connect(viewc, SIGNAL(requestOpenUrl(const QString&)),
00522           this, SLOT(openResource(const QString&)));
00523 
00524   connect(viewc, SIGNAL(resourceDataChanged(const QList<KLFLib::entryId>&)),
00525           this, SLOT(slotResourceDataChanged(const QList<KLFLib::entryId>&)));
00526   connect(resource, SIGNAL(resourcePropertyChanged(int)),
00527           this, SLOT(slotResourcePropertyChanged(int)));
00528   connect(resource, SIGNAL(subResourcePropertyChanged(const QString&, int)),
00529           this, SLOT(slotSubResourcePropertyChanged(const QString&, int)));
00530   connect(resource, SIGNAL(defaultSubResourceChanged(const QString&)),
00531           this, SLOT(slotDefaultSubResourceChanged(const QString&)));
00532 
00533   // progress reporting originating from resource (eg. database operations)
00534   connect(resource, SIGNAL(operationStartReportingProgress(KLFProgressReporter *, const QString&)),
00535           this, SLOT(slotStartProgress(KLFProgressReporter *, const QString&)));
00536   // progress reporting originating from view (eg. model updates)
00537   connect(viewc, SIGNAL(viewOperationStartReportingProgress(KLFProgressReporter *, const QString&)),
00538           this, SLOT(slotStartProgress(KLFProgressReporter *, const QString&)));
00539 
00540   // supply a context menu to view
00541   connect(viewc, SIGNAL(viewContextMenuRequested(const QPoint&)),
00542           this, SLOT(slotShowContextMenu(const QPoint&)));
00543 
00544 
00545   // create a list of view types to attempt to open, in a given priority order
00546   QStringList viewtypeident_try;
00547   //   * the argument to this function
00548   viewtypeident_try << viewTypeIdentifier;
00549   if ((resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources) &&
00550       (resource->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps)) {
00551     // * the sub-resource view type property (if applicable)
00552     viewtypeident_try
00553       << resource->subResourceProperty(resource->defaultSubResource(),
00554                                        KLFLibResourceEngine::SubResPropViewType).toString();
00555   }
00556   //   * the resource view type property
00557   viewtypeident_try << resource->viewType();
00558   //   * the suggested view type for this resource (as given by engine itself)
00559   viewtypeident_try << resource->suggestedViewTypeIdentifier();
00560   //   * the default view type suggested by the factory
00561   viewtypeident_try << KLFLibViewFactory::defaultViewTypeIdentifier();
00562   //   * a "default" view type (last resort, hoping it exists!)
00563   viewtypeident_try << QLatin1String("default");
00564 
00565   klfDbgT(": created resource. about to test view types.") ;
00566   klfDbg( "\tView types: "<<viewtypeident_try ) ;
00567 
00568   int k;
00569   // try each view type, first success is kept.
00570   for (k = 0; k < viewtypeident_try.size(); ++k) {
00571     if (viewtypeident_try[k].isEmpty())
00572       continue;
00573 
00574     KLFLibViewFactory *viewfactory =
00575       KLFLibViewFactory::findFactoryFor(viewtypeident_try[k]);
00576     if (viewfactory == NULL) {
00577       klfDbg( "can't find view factory for view type identifier "
00578               <<viewtypeident_try[k]<<"!" ) ;
00579       continue;
00580     }
00581     if ( ! viewfactory->canCreateLibView(viewtypeident_try[k], resource) ) {
00582       klfDbg( "incompatible view type identifier "<<viewtypeident_try[k]
00583               <<"for resource "<<resource->url()<<"." ) ;
00584       continue;
00585     }
00586     bool r = viewc->openView(viewtypeident_try[k]);
00587     if (!r) {
00588       klfDbg( "can't create view! viewtypeident="<<viewtypeident_try[k]<<"." ) ;
00589       continue;
00590     }
00591 
00592     klfDbgT(": found and instantiated good view type="<<viewtypeident_try[k]) ;
00593 
00594     // found good view type !
00595     resource->setViewType(viewtypeident_try[k]);
00596     // quit for() on first success.
00597     break;
00598   }
00599 
00600   klfDbgT(": requiring cat suggestions.") ;
00601 
00602   // get more category completions
00603   viewc->view()->wantMoreCategorySuggestions();
00604 
00605   // hide welcome page if it's shown
00606   if ((i = u->tabResources->indexOf(u->tabWelcome)) != -1)
00607     u->tabResources->removeTab(i);
00608 
00609   klfDbgT(": end of function") ;
00610 
00611   return true;
00612 }
00613 
00614 bool KLFLibBrowser::openResourceFromGuiState(const QUrl& url, const QVariantMap& guiState)
00615 {
00616   KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ;
00617   // peek into GUI state to open the correct view
00618   QString vti = guiState.value(QLatin1String("CurrentViewTypeIdentifier")).toString();
00619   klfDbg("view-type-identifier is "<<vti<<"; guiState is "<<guiState) ;
00620   bool result = openResource(url, NoChangeFlag, vti);
00621   if (!result)
00622     return false;
00623   klfDbg("restoring gui state..") ;
00624   KLFLibBrowserViewContainer *viewc = findOpenUrl(url);
00625   KLF_ASSERT_NOT_NULL( viewc, "can't find the view container we just opened!", return false ) ;
00626   viewc->loadGuiState(guiState);
00627   return true;
00628 }
00629 
00630 
00631 bool KLFLibBrowser::closeResource(const QUrl& url)
00632 {
00633   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00634 
00635   KLFLibBrowserViewContainer * w = findOpenUrl(url);
00636   if (w == NULL)
00637     return false;
00638 
00639   return slotResourceClose(w);
00640 }
00641 
00642 
00643 void KLFLibBrowser::updateResourceRoleFlags(KLFLibBrowserViewContainer *viewc, uint resroleflags)
00644 {
00645   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00646 
00647   KLF_ASSERT_NOT_NULL(viewc, "the viewc parameter is null!", return; ) ;
00648 
00649   if (resroleflags & NoChangeFlag)
00650     return;
00651 
00652   // only store flags that don't act 'now'
00653   resroleflags = resroleflags & ~NowMask;
00654 
00655   klfDbg("updating flags for resource="<<viewc->url()<<"; flags after mask="
00656          <<klfFmtCC("%#010x", resroleflags)) ;
00657 
00658   // If history resroleflags is set, then unset that flag to its previous owner (history role flag
00659   // is exclusive).
00660   // Same respectively for archive flag.
00661   uint exclusive_flag_list[] = { HistoryRoleFlag, ArchiveRoleFlag, 0 } ;
00662   int j;
00663   for (j = 0; exclusive_flag_list[j] != 0; ++j) {
00664     uint xflag = exclusive_flag_list[j];
00665     if (resroleflags & xflag) {
00666       // If we are about to set this flag to resource 'viewc', then make sure no one (else) has it
00667       int k;
00668       for (k = 0; k < pLibViews.size(); ++k) {
00669         if (pLibViews[k] == viewc)
00670           continue; // skip our targeted view
00671         uint fl = pLibViews[k]->resourceRoleFlags();
00672         if (fl & xflag) {
00673           // unset it
00674           pLibViews[k]->setResourceRoleFlags(fl & ~xflag);
00675         }
00676       }
00677     }
00678   }
00679 
00680   // now we can set the appropriate flags on the requested resource view
00681   viewc->setResourceRoleFlags(resroleflags);
00682 }
00683 
00684 
00685 void KLFLibBrowser::slotTabResourceShown(int tabIndex)
00686 {
00687   KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ;
00688   klfDbg( "\t tabIndex="<<tabIndex ) ;
00689 
00690   KLFLibBrowserViewContainer * viewc =
00691     qobject_cast<KLFLibBrowserViewContainer*>(u->tabResources->widget(tabIndex));
00692   if (viewc == NULL || tabIndex < 0) {
00693     emit resourceTabChanged(QUrl());
00694     return;
00695   }
00696 
00697   // redirect searches to the correct view
00698   u->searchBar->setSearchTarget(viewc);
00699 
00700   klfDbg("setting up view type menu...") ;
00701 
00702   // set up view type menu appropriately
00703   QList<QAction*> actions = viewc->viewTypeActions();
00704   QMenu *viewTypeMenu = u->aViewType->menu();
00705   if (viewTypeMenu == NULL) {
00706     viewTypeMenu = new QMenu(this);
00707     u->aViewType->setMenu(viewTypeMenu);
00708     KLF_DEBUG_WATCH_OBJECT(viewTypeMenu) ;
00709   }
00710   viewTypeMenu->clear();
00711   int k;
00712   for (k = 0; k < actions.size(); ++k) {
00713     viewTypeMenu->addAction(actions[k]);
00714   }
00715 
00716   QMenu * openSubResMenu = u->aOpenSubRes->menu();
00717   if (openSubResMenu == NULL) {
00718     openSubResMenu = new QMenu(this);
00719     u->aOpenSubRes->setMenu(openSubResMenu);
00720     KLF_DEBUG_WATCH_OBJECT(openSubResMenu) ;
00721   }
00722   openSubResMenu->clear();
00723   QList<QAction*> openSubResActions = viewc->openSubResourceActions();
00724   for (k = 0; k < openSubResActions.size(); ++k) {
00725     openSubResMenu->addAction(openSubResActions[k]);
00726   }
00727   if (openSubResActions.size() > 0)
00728     u->aOpenSubRes->setEnabled(true);
00729   else
00730     u->aOpenSubRes->setEnabled(false);
00731 
00732   // refresh selection-related displays
00733   KLFAbstractLibView *view = viewc->view();
00734   if (view != NULL)
00735     slotEntriesSelected(view->selectedEntries());
00736   slotRefreshResourceActionsEnabled();
00737 
00738   emit resourceTabChanged(viewc->url());
00739 }
00740 
00741 void KLFLibBrowser::slotShowTabContextMenu(const QPoint& pos)
00742 {
00743   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00744 
00745   int tab = u->tabResources->getTabAtPoint(pos);
00746   if (tab != -1) {
00747     u->tabResources->setCurrentIndex(tab);
00748   }
00749   pResourceMenu->popup(u->tabResources->mapToGlobal(pos));
00750 }
00751 
00752 void KLFLibBrowser::slotResourceRename()
00753 {
00754   slotResourceRename(false);
00755 }
00756 void KLFLibBrowser::slotResourceRenameSubResource()
00757 {
00758   slotResourceRename(true);
00759 }
00760 void KLFLibBrowser::slotResourceRename(bool renamingSubResource)
00761 {
00762   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00763   klfDbg("renamingSubResource="<<renamingSubResource) ;
00764 
00765   int tab = u->tabResources->currentIndex();
00766   KLFLibBrowserViewContainer * viewc = curView();
00767   if (tab < 0 || viewc == NULL)
00768     return;
00769 
00770   klfDbg( ": Rename! renamingSubResource="<<renamingSubResource ) ;
00771 
00772   KLFLibResourceEngine *res = viewc->resourceEngine();
00773 
00774   if ( ! renamingSubResource && ! res->canModifyProp(KLFLibResourceEngine::PropTitle) )
00775     return;
00776 
00777   if ( renamingSubResource &&
00778        ( !(res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources) ||
00779          !(res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) ||
00780          !(res->canModifySubResourceProperty(res->defaultSubResource(),
00781                                              KLFLibResourceEngine::SubResPropTitle))
00782          ) )
00783     return;
00784 
00785   QLineEdit * editor = new QLineEdit(u->tabResources);
00786   editor->setGeometry(u->tabResources->getTabRect(tab));
00787   editor->show();
00788   if (!renamingSubResource)
00789     editor->setText(res->title());
00790   else
00791     editor->setText(res->subResourceProperty(res->defaultSubResource(),
00792                                              KLFLibResourceEngine::SubResPropTitle).toString());
00793   editor->setFocus();
00794   editor->setProperty("tabURL", viewc->url());
00795   editor->setProperty("resourceTitleEditor", true);
00796   editor->setProperty("needsBackground", true);
00797   editor->setProperty("renamingSubResource", renamingSubResource);
00798   editor->setStyleSheet("");
00799   editor->installEventFilter(this);
00800 
00801   // kill editor if tab changes
00802   connect(u->tabResources, SIGNAL(currentChanged(int)), editor, SLOT(deleteLater()));
00803   connect(editor, SIGNAL(returnPressed()), this, SLOT(slotResourceRenameFinished()));
00804 }
00805 
00806 void KLFLibBrowser::slotResourceRenameFinished()
00807 {
00808   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00809 
00810   QObject * editor = sender();
00811   if (editor == NULL) {
00812     qWarning("KLFLibBrowser::slotResourceRenameFinished: no sender!");
00813     return;
00814   }
00815   bool isRenamingSubResource = editor->property("renamingSubResource").toBool();
00816   QUrl url = editor->property("tabURL").toUrl();
00817   KLFLibBrowserViewContainer * viewc = findOpenUrl(url);
00818   if (viewc == NULL) {
00819     qWarning()<<KLF_FUNC_NAME<<": can't find the resource with URL "<<url;
00820     return;
00821   }
00822   KLFLibResourceEngine *res = viewc->resourceEngine();
00823   QString text = editor->property("text").toString();
00824   if (!isRenamingSubResource)
00825     res->setTitle(text);
00826   else
00827     res->setSubResourceProperty(res->defaultSubResource(), KLFLibResourceEngine::SubResPropTitle,
00828                                 QVariant::fromValue<QString>(text));
00829 
00830   editor->deleteLater();
00831 }
00832 
00833 bool KLFLibBrowser::slotResourceClose(KLFLibBrowserViewContainer *view, bool force)
00834 {
00835   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00836 
00837   if (view == NULL)
00838     view = curView();
00839   if (view == NULL)
00840     return false;
00841 
00842   if (!force && view->resourceRoleFlags() & NoCloseRoleFlag) // sorry, can't close.
00843     return false;
00844 
00845   klfDbg( "Close! resflags="<<view->resourceRoleFlags() ) ;
00846 
00847   int tabindex = u->tabResources->indexOf(view);
00848   if (tabindex < 0) {
00849     qWarning("KLFLibBrowser::closeResource(url): can't find view in tab widget?!?\n"
00850              "\turl=%s, viewwidget=%p", qPrintable(view->url().toString()), view);
00851     return false;
00852   }
00853 
00854   if (!force && klfconfig.LibraryBrowser.confirmClose) {
00855     // ask user for confirmation
00856     QMessageBox::StandardButton btn =
00857       QMessageBox::question(this, tr("Close Resource"), tr("Do you want to close this resource?"),
00858                             QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes);
00859     if (btn != QMessageBox::Yes)
00860       return false;
00861   }
00862 
00863   u->tabResources->removeTab(tabindex);
00864   int index = pLibViews.indexOf(view);
00865   pLibViews.removeAt(index);
00866   // delete view and engine
00867   KLFLibResourceEngine *resource = view->resourceEngine();
00868   delete view;
00869   delete resource;
00870 
00871   if (u->tabResources->count() == 0)
00872     u->tabResources->addTab(u->tabWelcome, QIcon(":/pics/library.png"), tr("Library Browser"));
00873 
00874   return true;
00875 }
00876 
00877 void KLFLibBrowser::slotResourceProperties()
00878 {
00879   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00880 
00881   KLFLibBrowserViewContainer *view = curView();
00882   if (view == NULL) {
00883     qWarning("KLFLibBrowser::slotResourceProperties: NULL View!");
00884     return;
00885   }
00886   KLFLibResPropEditorDlg * dialog = new KLFLibResPropEditorDlg(view->resourceEngine(), this);
00887   dialog->show();
00888 }
00889 
00890 bool KLFLibBrowser::slotResourceNewSubRes()
00891 {
00892   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00893 
00894   KLFLibBrowserViewContainer *view = curView();
00895   if (view == NULL) {
00896     qWarning("KLFLibBrowser::slotResourceProperties: NULL View!");
00897     return false;
00898   }
00899   KLFLibResourceEngine *res = view->view()->resourceEngine();
00900   QString name = KLFLibNewSubResDlg::createSubResourceIn(res, this);
00901   if (name.isEmpty())
00902     return false;
00903 
00904   // see remark in comment below
00905   QUrl url = res->url();
00906   url.removeAllQueryItems("klfDefaultSubResource");
00907   url.addQueryItem("klfDefaultSubResource", name);
00908 
00909   klfDbg( "KLFLibBrowser::slotRes.New.S.Res(): Create sub-resource named "<<name<<", opening "<<url ) ;
00910 
00911   // in case of a view displaying all sub-resources, this also works because findOpenUrl() will find
00912   // that view and raise it.
00913   return openResource(url);
00914 }
00915 
00916 bool KLFLibBrowser::slotResourceDelSubRes()
00917 {
00918   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00919 
00920   KLFLibBrowserViewContainer *viewc = curView();
00921   KLF_ASSERT_NOT_NULL(viewc , "NULL View Container!" , return false; ) ;
00922   KLFAbstractLibView *view = viewc->view();
00923   KLF_ASSERT_NOT_NULL(view , "NULL View in container "<<viewc<<" !" , return false; ) ;
00924   KLFLibResourceEngine *res = view->resourceEngine();
00925   KLF_ASSERT_NOT_NULL(res , "NULL resource for view="<<view<<" !" , return false; ) ;
00926 
00927   KLF_ASSERT_CONDITION( res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResources ,
00928                         "Sub-resources are not supported in resource "<<res->url()<<"!"
00929                         " Cannot delete sub-resource!",
00930                         return false; ) ;
00931 
00932   if (res->subResourceList().size() <= 1) {
00933     QMessageBox::warning(this, tr("Error"),
00934                          tr("You may not delete the last remaining sub-resource of this resource."));
00935     klfDbg("Attempted to delete last remaining sub-resource"<<res->defaultSubResource()<<" of resource "
00936            <<res->url()<<". Not allowed.") ;
00937     return false;
00938   }
00939 
00940   QString curSubResource = res->defaultSubResource();
00941   QString curSubResTitle = curSubResource;
00942   if (res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) {
00943     QString t = res->subResourceProperty(curSubResource, KLFLibResourceEngine::SubResPropTitle).toString();
00944     if (!t.isEmpty())
00945       curSubResTitle = t;
00946   }
00947 
00948   // remove the current sub-resource: first ask user confirmation
00949 
00950   QMessageBox::StandardButton btn =
00951     QMessageBox::question(this, tr("Delete Sub-Resource", "[[msgbox title]]"),
00952                           tr("Do you really want to delete the sub-resource <b>%1</b>, "
00953                              "with all its contents, from resource <b>%2</b>?")
00954                           .arg(curSubResTitle, displayTitle(res)),
00955                           QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Cancel);
00956   if (btn != QMessageBox::Yes)
00957     return false;
00958 
00959   // now remove that sub-resource
00960   bool result = res->deleteSubResource(curSubResource);
00961 
00962   if (!result) {
00963     // report failure
00964     QMessageBox::critical(this, tr("Delete Sub-Resource", "[[msgbox title]]"),
00965                           tr("Deleting sub-resource failed."));
00966     return false;
00967   }
00968 
00969   // close the corresponding tab.
00970   slotResourceClose(viewc, true);
00971   return true;
00972 }
00973 
00974 bool KLFLibBrowser::slotResourceOpen()
00975 {
00976   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00977 
00978   QUrl url = KLFLibOpenResourceDlg::queryOpenResource(QUrl(), this);
00979   if (url.isEmpty())
00980     return false;
00981   bool r = openResource(url);
00982   if ( ! r ) {
00983     QMessageBox::critical(this, tr("Error"), tr("Failed to open library resource `%1'!")
00984                           .arg(url.toString()));
00985   }
00986   return r;
00987 }
00988 
00989 bool KLFLibBrowser::slotResourceNew()
00990 {
00991   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00992 
00993   KLFLibResourceEngine *resource = KLFLibCreateResourceDlg::createResource(QString(), this, this);
00994   if (resource == NULL)
00995     return false;
00996 
00997   return openResource(resource);
00998 }
00999 
01000 bool KLFLibBrowser::slotResourceSaveTo()
01001 {
01002   return false;
01003   // YET TO BE IMPLEMENTED... using the factories to get a save to... widget..
01004   //   KLFLibBrowserViewContainer *view = curView();
01005   //   if (view == NULL) {
01006   //     qWarning("KLFLibBrowser::slotResourceProperties: NULL View!");
01007   //     return false;
01008   //   }
01009 }
01010 
01011 void KLFLibBrowser::slotResourceDataChanged(const QList<KLFLib::entryId>& /*entryIdList*/)
01012 {
01013   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01014 
01015   //   KLFLibResourceEngine *resource = qobject_cast<KLFLibResourceEngine*>(sender());
01016   //   if (resource == NULL) {
01017   //     qWarning("KLFLibBrowser::slotResourceDataChanged: NULL sender or not resource!");
01018   //     return;
01019   //   }
01020   KLFLibBrowserViewContainer *viewc = qobject_cast<KLFLibBrowserViewContainer*>(sender());
01021   if (viewc == NULL) {
01022     qWarning()<<"KLFLibBrowser::slotResourceDataChanged: NULL sender or not KLFLibBro.ViewCont.!";
01023     return;
01024   }
01025   slotRefreshResourceActionsEnabled();
01026 
01027   KLFAbstractLibView * view = viewc->view();
01028   if (view == NULL) {
01029     qWarning()<<"KLFLibBrowser::slotResourceDataChanged: NULL view !!";
01030     return;
01031   }
01032   slotEntriesSelected(view->selectedEntries());
01033 }
01034 void KLFLibBrowser::slotResourcePropertyChanged(int propId)
01035 {
01036   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01037 
01038   KLFLibResourceEngine *resource = qobject_cast<KLFLibResourceEngine*>(sender());
01039   if (resource == NULL) {
01040     qWarning("KLFLibBrowser::slotResourcePropertyChanged: NULL sender or not resource!");
01041     return;
01042   }
01043   slotUpdateForResourceProperty(resource, propId);
01044 }
01045 
01046 void KLFLibBrowser::slotUpdateForResourceProperty(KLFLibResourceEngine *resource, int propId)
01047 {
01048   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01049   klfDbg("res="<<resource<<", propId="<<propId) ;
01050 
01051   slotRefreshResourceActionsEnabled();
01052 
01053   KLFLibBrowserViewContainer *view = findOpenResource(resource);
01054   if (view == NULL) {
01055     qWarning()<<"KLFLibBrowser::slotResourcePropertyChanged: can't find view for resource "
01056               <<resource<<", url="<<resource->url()<<"!";
01057     return;
01058   }
01059   if (propId == KLFLibResourceEngine::PropTitle || propId == KLFLibResourceEngine::PropLocked) {
01060     // the title is also affected by the locked state (# in front 
01061     u->tabResources->setTabText(u->tabResources->indexOf(view), displayTitle(resource));
01062   }
01063   if (propId == KLFLibResourceEngine::PropLocked) {
01064     u->tabResources->refreshTabReadOnly(u->tabResources->indexOf(view),
01065                                         !resource->canModifyData(KLFLibResourceEngine::AllActionsData));
01066     u->wEntryEditor
01067       ->setInputEnabled(resource->canModifyData(KLFLibResourceEngine::ChangeData));
01068     u->wEntryEditor->displayEntries(view->view()->selectedEntries());
01069   }
01070 }
01071 
01072 void KLFLibBrowser::slotSubResourcePropertyChanged(const QString& subResource, int propId)
01073 {
01074   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01075   Q_UNUSED(subResource) ;
01076   klfDbg("subResource="<<subResource<<", propId="<<propId) ;
01077 
01078   KLFLibResourceEngine *resource = qobject_cast<KLFLibResourceEngine*>(sender());
01079   if (resource == NULL) {
01080     qWarning("KLFLibBrowser::slotSubResourcePropertyChanged: NULL sender or not resource!");
01081     return;
01082   }
01083 
01086   if (propId < 0 || propId == KLFLibResourceEngine::SubResPropTitle) {
01087     // fake a resource property title change (updated stuff is the same) 
01088     slotUpdateForResourceProperty(resource, KLFLibResourceEngine::PropTitle);
01089   }
01090   if (propId < 0 || propId == KLFLibResourceEngine::SubResPropLocked) {
01091     // fake a resource property locked state change (updated stuff is the same)
01092     slotUpdateForResourceProperty(resource, KLFLibResourceEngine::PropLocked);
01093   }
01094 }
01095 
01096 void KLFLibBrowser::slotDefaultSubResourceChanged(const QString& subResource)
01097 {
01098   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01099   Q_UNUSED(subResource) ;
01100   klfDbg("subResource="<<subResource) ;
01101 
01102   KLFLibResourceEngine *resource = qobject_cast<KLFLibResourceEngine*>(sender());
01103   if (resource == NULL) {
01104     qWarning("KLFLibBrowser::slotDefaultSubResourceChanged: NULL sender or not resource!");
01105     return;
01106   }
01107   // view already does a full refresh. We will just refresh the tab title.
01108   // fake a resource property title/locked state change (updated stuff is the same)
01109   slotUpdateForResourceProperty(resource, KLFLibResourceEngine::PropTitle);
01110   slotUpdateForResourceProperty(resource, KLFLibResourceEngine::PropLocked);
01111 }
01112 
01113 
01114 void KLFLibBrowser::slotRestoreWithStyle()
01115 {
01116   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01117 
01118   KLFAbstractLibView * view = curLibView();
01119   if ( view == NULL )
01120     return;
01121   view->restoreWithStyle();
01122 }
01123 
01124 void KLFLibBrowser::slotRestoreLatexOnly()
01125 {
01126   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01127 
01128   KLFAbstractLibView * view = curLibView();
01129   if ( view == NULL )
01130     return;
01131   view->restoreLatexOnly();
01132 }
01133 
01134 void KLFLibBrowser::slotDeleteSelected()
01135 {
01136   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01137 
01138   KLFAbstractLibView * view = curLibView();
01139   if ( view == NULL )
01140     return;
01141   KLFLibResourceEngine * resource = view->resourceEngine();
01142   if ( !resource->canModifyData(KLFLibResourceEngine::DeleteData) )
01143     return;
01144 
01145   QList<KLFLib::entryId> sel = view->selectedEntryIds();
01146   klfDbg("selected "<<sel.size()<<" items:" <<sel);
01147 
01148   if (sel.isEmpty())
01149     return;
01150 
01151   QMessageBox::StandardButton res
01152     = QMessageBox::question(this, tr("Delete?"),
01153                             tr("Delete %n selected item(s) from resource \"%1\"?", "", sel.size())
01154                             .arg(resource->title()),
01155                             QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Cancel);
01156   if (res != QMessageBox::Yes)
01157     return; // abort action
01158   
01159   resource->deleteEntries(sel);
01160 }
01161 
01162 void KLFLibBrowser::slotRefreshResourceActionsEnabled()
01163 {
01164   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01165 
01166   bool master = false;
01167   bool canrename = false;
01168   bool canrenamesubres = false;
01169   bool cansaveto = false;
01170   bool cannewsubres = false;
01171   bool candelsubres = false;
01172   uint resrolefl = 0;
01173   uint resfeatureflags = 0;
01174 
01175   KLFLibBrowserViewContainer * view = curView();
01176   if ( view != NULL ) {
01177     master = true;
01178     KLFLibResourceEngine *res = view->resourceEngine();
01179     canrename = res->canModifyProp(KLFLibResourceEngine::PropTitle);
01180     resfeatureflags = res->supportedFeatureFlags();
01181     cansaveto = (resfeatureflags & KLFLibResourceEngine::FeatureSaveTo);
01182     resrolefl = view->resourceRoleFlags();
01183     cannewsubres = (resfeatureflags & KLFLibResourceEngine::FeatureSubResources) &&
01184       (res->canCreateSubResource());
01185     candelsubres = (resfeatureflags & KLFLibResourceEngine::FeatureSubResources) &&
01186       res->canDeleteSubResource(res->defaultSubResource()) ;
01187     canrenamesubres = (resfeatureflags & KLFLibResourceEngine::FeatureSubResources) &&
01188       (resfeatureflags & KLFLibResourceEngine::FeatureSubResourceProps) &&
01189       res->canModifySubResourceProperty(res->defaultSubResource(),
01190                                         KLFLibResourceEngine::SubResPropTitle) ;
01191   }
01192 
01193   u->aRename->setEnabled(canrename);
01194   u->aRenameSubRes->setEnabled(canrenamesubres);
01195   u->aProperties->setEnabled(master);
01196   u->aNewSubRes->setEnabled(master && cannewsubres);
01197   u->aDelSubRes->setEnabled(master && candelsubres);
01198   u->aSaveTo->setEnabled(master && cansaveto);
01199   u->aNew->setEnabled(true);
01200   u->aOpen->setEnabled(true);
01201   u->aClose->setEnabled(master && !(resrolefl & NoCloseRoleFlag));
01202 }
01203 
01204 
01205 
01206 void KLFLibBrowser::slotEntriesSelected(const KLFLibEntryList& entries)
01207 {
01208   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01209   klfDbg( "(): "<<entries ) ;
01210   if (entries.size()>=1)
01211     klfDbg( "Tag of first selected entry="<<entries[0].property(KLFLibEntry::Tags) ) ;
01212 
01213   KLFAbstractLibView *view = curLibView();
01214   if (view != NULL) {
01215     u->wEntryEditor
01216       ->setInputEnabled(view->resourceEngine()->canModifyData(KLFLibResourceEngine::ChangeData));
01217   }
01218 
01219   u->wEntryEditor->displayEntries(entries);
01220 
01221   u->btnDelete->setEnabled(entries.size() > 0);
01222   u->aDelete->setEnabled(u->btnDelete->isEnabled());
01223   u->btnRestore->setEnabled(entries.size() == 1);
01224 
01225   emit libEntriesSelected(entries);
01226 }
01227 
01228 void KLFLibBrowser::slotAddCategorySuggestions(const QStringList& catlist)
01229 {
01230   klfDbg( "KLFLibBrowser: got category suggestions: "<<catlist ) ;
01231   u->wEntryEditor->addCategorySuggestions(catlist);
01232 }
01233 
01234 void KLFLibBrowser::slotShowContextMenu(const QPoint& pos)
01235 {
01236   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01237 
01238   KLFAbstractLibView * view = curLibView();
01239   if ( view == NULL )
01240     return;
01241 
01242   QMenu *menu = new QMenu(view);
01243 
01244   QAction *a1 = menu->addAction(QIcon(":/pics/restoreall.png"), tr("Restore latex formula and style"),
01245                                 view, SLOT(restoreWithStyle()));
01246   QAction *a2 = menu->addAction(QIcon(":/pics/restore.png"), tr("Restore latex formula only"),
01247                                 view, SLOT(restoreLatexOnly()));
01248   menu->addSeparator();
01249   // NOTE: the QKeySequences given here are only for display in the context menu. Their functionality
01250   // is due to additional QShortcuts declared in the constructor. (!) (reason: these actions are
01251   // short-lived, and having global actions would require keeping their enabled status up-to-date
01252   // + we want to add view-given context menu actions dynamically)
01253   QAction *acut = menu->addAction(QIcon(":/pics/cut.png"), tr("Cut"), this, SLOT(slotCut()),
01254                                   QKeySequence::Cut);
01255   QAction *acopy = menu->addAction(QIcon(":/pics/copy.png"), tr("Copy"), this, SLOT(slotCopy()),
01256                                   QKeySequence::Copy);
01257   QAction *apaste = menu->addAction(QIcon(":/pics/paste.png"), tr("Paste"), this, SLOT(slotPaste()),
01258                                   QKeySequence::Paste);
01259   menu->addSeparator();
01260   QAction *adel = menu->addAction(QIcon(":/pics/delete.png"), tr("Delete from library"),
01261                                   this, SLOT(slotDeleteSelected()), QKeySequence::Delete);
01262   menu->addSeparator();
01263 
01264   QMenu *copytomenu = new QMenu(menu);
01265   QMenu *movetomenu = new QMenu(menu);
01266   int k;
01267   QAction *acopythere, *amovethere;
01268   int n_destinations = 0;
01269   for (k = 0; k < pLibViews.size(); ++k) {
01270     if (pLibViews[k]->url() == view->url()) // skip this view
01271       continue;
01272     KLFLibResourceEngine *res = pLibViews[k]->resourceEngine();
01273     QUrl viewurl = pLibViews[k]->url();
01274     n_destinations++;
01275     acopythere = copytomenu->addAction(displayTitle(res), this, SLOT(slotCopyToResource()));
01276     acopythere->setProperty("resourceViewUrl", viewurl);
01277     amovethere = movetomenu->addAction(displayTitle(res), this, SLOT(slotMoveToResource()));
01278     amovethere->setProperty("resourceViewUrl", viewurl);
01279     if (!res->canModifyData(KLFLibResourceEngine::InsertData)) {
01280       acopythere->setEnabled(false);
01281       amovethere->setEnabled(false);
01282     }
01283   }
01284   QAction *acopyto = menu->addMenu(copytomenu);
01285   acopyto->setText(tr("Copy to"));
01286   acopyto->setIcon(QIcon(":/pics/copy.png"));
01287   QAction *amoveto = menu->addMenu(movetomenu);
01288   amoveto->setText(tr("Move to"));
01289   amoveto->setIcon(QIcon(":/pics/move.png"));
01290 
01291   menu->addSeparator();
01292   menu->addMenu(pResourceMenu);
01293 
01294   // Needed for when user pops up a menu without selection (ie. short list, free white space under)
01295   KLFLibEntryList selected = view->selectedEntries();
01296   bool cancopy = (selected.size() > 0) && n_destinations;
01297   bool canre = (selected.size() == 1);
01298   bool candel = view->resourceEngine()->canModifyData(KLFLibResourceEngine::DeleteData);
01299   bool canpaste = KLFAbstractLibEntryMimeEncoder::canDecodeMimeData(QApplication::clipboard()->mimeData());
01300   a1->setEnabled(canre);
01301   a2->setEnabled(canre);
01302   adel->setEnabled(candel && selected.size());
01303   acut->setEnabled(cancopy && candel);
01304   acopy->setEnabled(cancopy);
01305   apaste->setEnabled(canpaste);
01306   acopyto->setEnabled(cancopy);
01307   amoveto->setEnabled(cancopy && candel);
01308 
01309   // add view's own actions
01310 
01311   QList<QAction*> viewActions = view->addContextMenuActions(pos);
01312   if (viewActions.size())
01313     menu->addSeparator(); // separate view's menu items from ours
01314   for (k = 0; k < viewActions.size(); ++k) {
01315     klfDbg( "Added action "<<k<<": "<<viewActions[k] ) ;
01316     menu->addAction(viewActions[k]);
01317   }
01318 
01319   menu->popup(view->mapToGlobal(pos));
01320 }
01321 
01322 
01323 
01324 void KLFLibBrowser::slotMetaInfoChanged(const QMap<int,QVariant>& props)
01325 {
01326   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01327 
01328   QWidget *w = u->tabResources->currentWidget();
01329   KLFLibBrowserViewContainer *wviewc = qobject_cast<KLFLibBrowserViewContainer*>(w);
01330   if (wviewc == NULL) {
01331     qWarning("Current view is not a KLFLibBrowserViewContainer or no current tab widget!");
01332     return;
01333   }
01334   if (props.isEmpty()) {
01335     klfDbg("no changes!");
01336     return;
01337   }
01338   KLFAbstractLibView * wview = wviewc->view();
01339   if ( wview == NULL )
01340     return;
01341   QList<KLFLib::entryId> selected = wview->selectedEntryIds();
01342   KLFLibResourceEngine *resource = wview->resourceEngine();
01343   QList<int> keys = props.keys();
01344   QList<QVariant> values;
01345   int k;
01346   for (k = 0; k < keys.size(); ++k)
01347     values << props[keys[k]];
01348   bool r = resource->changeEntries(selected, keys, values);
01349   if ( ! r ) {
01350     QMessageBox::warning(this, tr("Error"),
01351                          tr("Failed to write meta-information!"));
01352     // and refresh display
01353     slotEntriesSelected(wview->selectedEntries());
01354     return;
01355   }
01356 
01357   // ensure that exactly the modified items are selected, as view's refresh mechanism does
01358   // not garantee to preserve selection
01359   wview->selectEntries(selected);
01360 
01361   // if we categorized/tagged a formula in the history resource, copy it to the archive if the relevant
01362   // setting is enabled
01363   if (klfconfig.LibraryBrowser.historyTagCopyToArchive && !props.isEmpty()) {
01364     KLFLibBrowserViewContainer *vHistory = findSpecialResource(HistoryRoleFlag);
01365     KLFLibBrowserViewContainer *vArchive = findSpecialResource(ArchiveRoleFlag);
01366     klfDbg("vHistory="<<vHistory<<", vArchive="<<vArchive<<", wviewc="<<wviewc) ;
01367     if (vHistory != NULL && vArchive != NULL && vHistory != vArchive  &&
01368         vHistory == wviewc) {
01369       klfDbg("categorized formula in history. copying it to archive");
01370       // copy the formula from history to archive
01371       KLFLibEntryList entryList = wview->selectedEntries();
01372       if (entryList.isEmpty()) {
01373         qWarning()<<KLF_FUNC_NAME<<": no selected entries ?!?";
01374       } else {
01375         KLFAbstractLibView *archiveView = vArchive->view();
01376         KLFLibResourceEngine *archiveRes = vArchive->resourceEngine();
01377         if (archiveRes == NULL || archiveView == NULL) {
01378           qWarning()<<KLF_FUNC_NAME<<": archiveRes or archiveView is NULL ?!?";
01379         } else {
01380           QList<KLFLib::entryId> insertedIds = archiveRes->insertEntries(entryList);
01381           if (!insertedIds.size() || insertedIds.contains(-1)) {
01382             QMessageBox::critical(this, tr("Error"), tr("Error copying the given items to the archive!"));
01383           } else {
01384             u->tabResources->setCurrentWidget(vArchive);
01385             // and select those items in archive that were inserted.
01386             archiveView->selectEntries(insertedIds);
01387           }
01388         }
01389       }
01390     }
01391   }
01392 }
01393 
01394 void KLFLibBrowser::slotCopyToResource()
01395 {
01396   slotCopyMoveToResource(sender(), false);
01397 }
01398 
01399 void KLFLibBrowser::slotMoveToResource()
01400 {
01401   slotCopyMoveToResource(sender(), true);
01402 }
01403 
01404 void KLFLibBrowser::slotCopyMoveToResource(QObject *action, bool move)
01405 {
01406   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01407 
01408   QUrl destUrl = action->property("resourceViewUrl").toUrl();
01409   if (destUrl.isEmpty()) {
01410     qWarning()<<"KLFLibBrowser::slotCopyMoveToResource(): bad sender property ! sender is a `"
01411               <<action->metaObject()->className()<<"'; expected QAction with 'resourceViewUrl' property set.";
01412     return;
01413   }
01414   KLFAbstractLibView *sourceView = curLibView();
01415   if (sourceView == NULL) {
01416     qWarning()<<"KLFLibBrowser::slotCopyMoveToResource(): source view is NULL!";
01417     return;
01418   }
01419   KLFLibBrowserViewContainer *destViewC = findOpenUrl(destUrl);
01420   if (destViewC == NULL || destViewC->view() == NULL) {
01421     qWarning()<<"KLFLibBrowser::slotCopyMoveToResource(): can't find dest view url for URL="<<destUrl<<" !";
01422     return;
01423   }
01424   KLFAbstractLibView *destView = destViewC->view();
01425   // now do the copy/move:
01426   slotCopyMoveToResource(destView, sourceView, move);
01427 }
01428 
01429 void KLFLibBrowser::slotCopyMoveToResource(KLFAbstractLibView *dest, KLFAbstractLibView *source,
01430                                            bool move)
01431 {
01432   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01433 
01434   QList<KLFLib::entryId> selectedids = source->selectedEntryIds();
01435   KLFLibEntryList items = source->selectedEntries();
01436 
01437   QList<int> inserted = dest->resourceEngine()->insertEntries(items);
01438   if ( inserted.isEmpty() || inserted.contains(-1) ) {
01439     QString msg = move ? tr("Failed to move the selected items.")
01440       : tr("Failed to copy the selected items.");
01441     QMessageBox::critical(this, tr("Error"), msg, QMessageBox::Ok, QMessageBox::Ok);
01442     return;
01443   }
01444   if (move)
01445     source->resourceEngine()->deleteEntries(selectedids);
01446 }
01447 
01448 void KLFLibBrowser::slotCut()
01449 {
01450   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01451 
01452   KLFAbstractLibView * view = curLibView();
01453   if ( view == NULL )
01454     return;
01455   if ( view->selectedEntries().size() == 0 ||
01456        !view->resourceEngine()->canModifyData(KLFLibResourceEngine::DeleteData) )
01457     return;
01458 
01459   QList<KLFLib::entryId> selected = view->selectedEntryIds();
01460   slotCopy();
01461   view->resourceEngine()->deleteEntries(selected);
01462 }
01463 void KLFLibBrowser::slotCopy()
01464 {
01465   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01466 
01467   KLFAbstractLibView * view = curLibView();
01468   if ( view == NULL )
01469     return;
01470   if ( view->selectedEntries().size() == 0 )
01471     return;
01472 
01473   KLFLibEntryList elist = view->selectedEntries();
01474   QVariantMap vprops;
01475   vprops["Url"] = view->url(); // originating URL
01476 
01477   QMimeData *mimeData = KLFAbstractLibEntryMimeEncoder::createMimeData(elist, vprops);
01478   QApplication::clipboard()->setMimeData(mimeData);
01479 }
01480 void KLFLibBrowser::slotPaste()
01481 {
01482   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01483 
01484   KLFAbstractLibView * view = curLibView();
01485   if ( view == NULL )
01486     return;
01487 
01488   KLFLibEntryList elist;
01489   QVariantMap vprops;
01490 
01491   const QMimeData* mimeData = QApplication::clipboard()->mimeData();
01492   bool result =
01493     KLFAbstractLibEntryMimeEncoder::decodeMimeData(mimeData, &elist, &vprops);
01494   if (!result) {
01495     QMessageBox::critical(this, tr("Error"), tr("The clipboard doesn't contain any appropriate data."));
01496     return;
01497   }
01498 
01499   klfDbg( ": Pasting data! props="<<vprops ) ;
01500   QList<KLFLib::entryId> inserted = view->resourceEngine()->insertEntries(elist);
01501   if (inserted.isEmpty() || inserted.contains(-1)) {
01502     QMessageBox::critical(this, tr("Error"), tr("Error pasting items"));
01503   }
01504 }
01505 
01506 
01507 void KLFLibBrowser::slotOpenAll()
01508 {
01509   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01510 
01511   QStringList exportFilterList;
01512   QStringList filterlist;
01513   QString exportFilter;
01514   QList<KLFLibBasicWidgetFactory::LocalFileType> locfiletypes = KLFLibBasicWidgetFactory::localFileTypes();
01515   int k;
01516   for (k = 0; k < locfiletypes.size(); ++k) {
01517     exportFilterList << locfiletypes[k].filter;
01518     filterlist << locfiletypes[k].filepattern;
01519   }
01520   exportFilterList.prepend(tr("All Known Library Files (%1)").arg(filterlist.join(" ")));
01521   exportFilterList << tr("All Files (*)");
01522   exportFilter = exportFilterList.join(";;");
01523   QString selectedFilter;
01524   QString dir = klfconfig.LibraryBrowser.lastFileDialogPath;
01525   QString fn = QFileDialog::getOpenFileName(this, tr("Open Library File"), dir, exportFilter, &selectedFilter);
01526   if (fn.isEmpty())
01527     return;
01528 
01529   klfconfig.LibraryBrowser.lastFileDialogPath = QFileInfo(fn).absolutePath();
01530 
01531   int ifilter = exportFilterList.indexOf(selectedFilter);
01532   ifilter--; // index in locfiletypes now
01533   QString selectedScheme;
01534   if (ifilter >= 0 && ifilter < locfiletypes.size()) {
01535     selectedScheme = locfiletypes[ifilter].scheme;
01536   } else {
01537     selectedScheme = KLFLibBasicWidgetFactory::guessLocalFileScheme(fn);
01538   }
01539   if (!QFileInfo(fn).isReadable()) {
01540     qWarning()<<KLF_FUNC_NAME<<": The given file name is not readable: "<<fn;
01541     QMessageBox::critical(this, tr("Error"), tr("The given file cannot be read: %1").arg(fn));
01542     return;
01543   }
01544   if (selectedScheme.isEmpty()) {
01545     QMessageBox::critical(this, tr("Error"), tr("Unknown open file scheme!"));
01546     return;
01547   }
01548 
01549   QUrl baseUrl = QUrl::fromLocalFile(fn);
01550   baseUrl.setScheme(selectedScheme);
01551   QStringList subreslist = KLFLibEngineFactory::listSubResources(baseUrl);
01552   for (k = 0; k < subreslist.size(); ++k) {
01553     QUrl url = baseUrl;
01554     url.addQueryItem("klfDefaultSubResource", subreslist[k]);
01555     bool r = openResource(url);
01556     if ( !r )
01557       QMessageBox::critical(this, tr("Error"), tr("Failed to open resource %1!").arg(url.toString()));
01558   }
01559 }
01560 
01561 bool KLFLibBrowser::slotExport()
01562 {
01563   KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ;
01564 
01565   QList<QUrl> exportUrls;
01566   KLFLibResourceEngine *exportRes = KLFLibExportDialog::showExportDialogCreateResource(this, &exportUrls);
01567   if (exportRes == NULL) {
01568     return false;
01569   }
01570   exportRes->setTitle(tr("Export %1").arg(QDateTime::currentDateTime()
01571                                           .toString(Qt::DefaultLocaleShortDate)));
01572 
01573   klfDbg("Export: to resource "<<exportRes->url().toString()<<". Export: "<<exportUrls);
01574 
01575   // visual feedback for export
01576   KLFProgressDialog pdlg(QString(), this);
01577   connect(exportRes, SIGNAL(operationStartReportingProgress(KLFProgressReporter *,
01578                                                             const QString&)),
01579           &pdlg, SLOT(startReportingProgress(KLFProgressReporter *)));
01580   pdlg.setAutoClose(false);
01581   pdlg.setAutoReset(false);
01582 
01583   bool fail = false;
01584   QStringList subresources;
01585   int k;
01586   for (k = 0; k < exportUrls.size(); ++k) {
01587     klfDbg("Exporting "<<exportUrls[k]<<" ...");
01588     QUrl u = exportUrls[k];
01589     QString usr = u.hasQueryItem("klfDefaultSubResource")
01590       ? u.queryItemValue("klfDefaultSubResource")
01591       : QString();
01592     QString sr = usr;
01593     if (usr.isEmpty()) {
01594       // the resource doesn't support sub-resources
01595       usr = u.path().section('/', -1, -1, QString::SectionSkipEmpty); // last path element
01596     }
01597     usr.replace(QRegExp("[^a-zA-Z0-9_-]"), "_");
01598     QString subres = usr;
01599     int counter = 1;
01600     while (subresources.contains(subres))
01601       subres = usr+"_"+QString::number(counter++);
01602     // subres is the name of the subresource we will create
01603     bool r = exportRes->createSubResource(subres);
01604     if (!r) {
01605       fail = true;
01606       qWarning()<<KLF_FUNC_NAME<<" exporting "<<u<<" failed: can't create sub-resource "<<subres<<"!";
01607       continue;
01608     }
01609     subresources.append(subres);
01610     KLFLibResourceEngine *res = getOpenResource(u);
01611     if (res == NULL) {
01612       fail = true;
01613       qWarning()<<KLF_FUNC_NAME<<" can't find open resource="<<u<<" !";
01614       continue;
01615     }
01616     QString title;
01617     if (usr.isEmpty()) {
01618       title = res->title();
01619     } else {
01620       if (res->supportedFeatureFlags() & KLFLibResourceEngine::FeatureSubResourceProps) {
01621         title = res->title() + ": " +
01622           res->subResourceProperty(usr, KLFLibResourceEngine::SubResPropTitle).toString();
01623       } else {
01624         title = res->title() + ": " + usr;
01625       }
01626     }
01627     exportRes->setSubResourceProperty(subres, KLFLibResourceEngine::SubResPropTitle, title);
01628 
01629     pdlg.setDescriptiveText(tr("Exporting ... %3 (%1/%2)")
01630                             .arg(k+1).arg(exportUrls.size()).arg(title));
01631 
01632     QList<KLFLibResourceEngine::KLFLibEntryWithId> elistwid = res->allEntries(usr);
01635     KLFLibEntryList elist;
01636     int j;
01637     for (j = 0; j < elistwid.size(); ++j)
01638       elist << elistwid[j].entry;
01639 
01640     QList<KLFLib::entryId> insertedIds = exportRes->insertEntries(subres, elist);
01641     if (!insertedIds.size() || insertedIds.contains(-1)) {
01642       QMessageBox::critical(this, tr("Error"), tr("Error exporting items!"));
01643     }
01644   }
01645 
01646   // remove our dummy sub-resource that was created with the resource
01647   // name was set in klflibbrowser_p.h: KLFLibExportDialog::showExportDi...()
01648   exportRes->deleteSubResource(QLatin1String("export_xtra"));
01649 
01650   // important, as it will cause save() to be called on legacy engines, otherwise we will just
01651   // have a zombie resource waiting for something
01652   delete exportRes;
01653 
01654   return !fail;
01655 }
01656 
01657 bool KLFLibBrowser::slotExportSelection()
01658 {
01659   KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME) ;
01660 
01661   // need to fetch selection from current view
01662   KLFAbstractLibView *view = curLibView();
01663   if (view == NULL) {
01664     qWarning("KLFLibBrowser::slotResourceProperties: NULL View!");
01665     return false;
01666   }
01667 
01668   // select and open target file
01669   KLFLibEngineFactory *factory = KLFLibLegacyEngineFactory::findFactoryFor("klf+legacy");
01670   if (factory == NULL) {
01671     qWarning()<<KLF_FUNC_NAME<<": Can't create KLFLibLegacyEngineFactory object (\"klf+legacy\") ?!?";
01672     return false;
01673   }
01674   QString filter = factory->schemeTitle(QLatin1String("klf+legacy")) + " (*.klf)";
01675   QString path = klfconfig.LibraryBrowser.lastFileDialogPath;
01676   QString fileName = QFileDialog::getSaveFileName(this, tr("Export selection to file..."), path, filter);
01677 
01678   if (fileName.isEmpty()) {
01679     klfDbg("Canceled by user.");
01680     return false;
01681   }
01682 
01683   if (QFile::exists(fileName)) {
01684     // erase it. the file dialog already asked for overwrite confirmation.
01685     if ( ! QFile::remove(fileName) ) {
01686       QMessageBox::critical(this, tr("Error"), tr("Failed to overwrite file %1").arg(fileName));
01687       qWarning()<<KLF_FUNC_NAME<<": Can't overwrite file "<<fileName;
01688       return false;
01689     }
01690   }
01691 
01692   klfDbg("Exporting to file "<<fileName);
01693 
01694   // get selected entries
01695   KLFLibEntryList entryList = view->selectedEntries();
01696 
01697   // create file resource
01698   KLFLibWidgetFactory::Parameters param;
01699   param["klfScheme"] = QLatin1String("klf+legacy");
01700   param["Filename"] = fileName;
01701   param["klfDefaultSubResource"] = tr("Export", "[[export selection default sub-resource name]]");
01702   KLFLibResourceEngine *resource = factory->createResource(QLatin1String("klf+legacy"), param, this);
01703 
01704   if (resource == NULL) {
01705     QMessageBox::critical(this, tr("Error"), tr("Failed to create export file %1!").arg(fileName));
01706     return false;
01707   }
01708 
01709   QList<KLFLib::entryId> insertedIds = resource->insertEntries(entryList);
01710   if (!insertedIds.size() || insertedIds.contains(-1)) {
01711     QMessageBox::critical(this, tr("Error"), tr("Error exporting items!"));
01712   }
01713 
01714   // important, as it will cause save() to be called on legacy engines, otherwise we will just
01715   // have a zombie resource waiting for something
01716   delete resource;
01717 
01718   return true;
01719 }
01720 
01721 void KLFLibBrowser::slotStartProgress(KLFProgressReporter *progressReporter, const QString& text)
01722 {
01723   KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
01724   klfDbg( ": min,max="<<progressReporter->min()<<","<<progressReporter->max()
01725           <<"; text="<<text ) ;
01726 
01727   KLFProgressDialog *pdlg = new KLFProgressDialog(false, QString(), this);
01728 
01729   pdlg->startReportingProgress(progressReporter, text);
01730 
01731   pdlg->setProperty("klf_libbrowser_pdlg_want_hideautodelete", QVariant(true));
01732   pdlg->installEventFilter(this);
01733 }
01734 
01735 
01736 
01737 bool KLFLibBrowser::event(QEvent *e)
01738 {
01739   if (e->type() == QEvent::KeyPress) {
01740     QKeyEvent *ke = (QKeyEvent*)e;
01741     if (ke->key() == Qt::Key_F8 && ke->modifiers() == 0) {
01742       hide();
01743       e->accept();
01744       return true;
01745     }
01746   }
01747   return QWidget::event(e);
01748 }
01749 
01750 void KLFLibBrowser::timerEvent(QTimerEvent *event)
01751 {
01752   QWidget::timerEvent(event);
01753 }
01754 
01755 
01756 void KLFLibBrowser::showEvent(QShowEvent *event)
01757 {
01758   // update some last-minute stuff
01759   // like the tab colors (which could have changed upon setting a skin)
01760   int k;
01761   for (k = 0; k < pLibViews.size(); ++k) {
01762     KLFLibBrowserViewContainer *viewc = pLibViews[k];
01763     KLFLibResourceEngine *resource = viewc->resourceEngine();
01764     u->tabResources->refreshTabReadOnly(u->tabResources->indexOf(viewc),
01765                                         !resource->canModifyData(KLFLibResourceEngine::AllActionsData));
01766   }
01767   // and call superclass
01768   QWidget::showEvent(event);
01769 }
01770 
01771 

Generated by doxygen 1.7.3