xref: /aoo41x/main/svx/source/dialog/hyprlink.cxx (revision f6e50924)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <tools/urlobj.hxx>
27 #include <vcl/msgbox.hxx>
28 #include <unotools/configitem.hxx>
29 #include <unotools/cmdoptions.hxx>
30 #include <svtools/inetimg.hxx>
31 #include <svl/urlbmk.hxx>
32 #include <svl/eitem.hxx>
33 #include <svl/stritem.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <sfx2/imgmgr.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <svl/urihelper.hxx>
39 #include <sfx2/objsh.hxx>
40 #include <comphelper/processfactory.hxx>
41 
42 #include "svx/hlnkitem.hxx"
43 #include <svx/dialogs.hrc>
44 #include "hyprlink.hrc"
45 #include <svx/dialmgr.hxx>
46 #include "svx/hyprlink.hxx"
47 #include "hyprdlg.hxx"
48 
49 using namespace ::rtl;
50 using namespace ::com::sun::star;
51 
52 // -----------------------------------------------------------------------
53 
54 class SearchDefaultConfigItem_Impl : public ::utl::ConfigItem
55 {
56     OUString    sDefaultEngine;
57 public:
58     SearchDefaultConfigItem_Impl();
59     ~SearchDefaultConfigItem_Impl();
60 
61     const OUString&    GetDefaultSearchEngine(){ return sDefaultEngine;}
62     virtual void            Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
63     virtual void            Commit();
64 };
65 
66 /*-- 11.11.2003 14:20:59---------------------------------------------------
67 
68   -----------------------------------------------------------------------*/
69 SearchDefaultConfigItem_Impl::SearchDefaultConfigItem_Impl() :
70         ConfigItem(OUString::createFromAscii("Inet/DefaultSearchEngine"))
71 {
72     uno::Sequence<OUString> aNames(1);
73     aNames.getArray()[0] = OUString::createFromAscii("Name");
74     uno::Sequence< uno::Any > aValues = GetProperties(aNames);
75     aValues.getConstArray()[0] >>= sDefaultEngine;
76 }
77 /*-- 11.11.2003 14:21:00---------------------------------------------------
78 
79   -----------------------------------------------------------------------*/
80 SearchDefaultConfigItem_Impl::~SearchDefaultConfigItem_Impl()
81 {
82 }
83 
84 void SearchDefaultConfigItem_Impl::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
85 {
86 }
87 
88 void SearchDefaultConfigItem_Impl::Commit()
89 {
90 }
91 
92 /*************************************************************************
93 |*
94 |* Dialog zum Einf"ugen/"Andern eines Hyperlink
95 |*
96 \************************************************************************/
97 
98 SvxHyperlinkDlg::SvxHyperlinkDlg( SfxBindings *_pBindings, Window* pParent) :
99 
100     ToolBox             ( pParent, SVX_RES( RID_SVXDLG_HYPERLINK ) ),
101     SfxControllerItem   ( SID_HYPERLINK_SETLINK, *_pBindings ),
102 
103 	aForwarder			( SID_HYPERLINK_GETLINK, *this ),
104 	aHyperlinkDlgForward( SID_HYPERLINK_DIALOG , *this),
105 
106 	aNameCB				( this, SVX_RES( CB_NAME ) ),
107 	aUrlFT				( this, SVX_RES( FT_URL ) ),
108 	aUrlCB				( this, SVX_RES( CB_URL ) ),
109     aSearchConfig       (sal_True),
110 	sAddress			( SVX_RES( STR_ADDRESS ) ),
111 	sExplorer			( SVX_RES( STR_EXPLORER ) ),
112 	sSearchTitle		( SVX_RES( STR_BOOKMARK_SEARCH ) ),
113 	aLinkPopup			( SVX_RES( RID_SVXMN_HYPERLINK ) ),
114 	pTargetMenu			( NULL ),
115 
116     bNoDoc              ( sal_True ),
117     bSend               ( sal_False ),
118     bHasOldName         ( sal_False ),
119     bHtmlMode           ( sal_False )
120 
121 {
122 	FreeResource();
123 
124     mpManager = SfxImageManager::GetImageManager( 0 );
125 	mpManager->RegisterToolBox( this );
126 
127 	SetImages();
128 
129     // save initial size
130 	nMaxWidth = GetSizePixel().Width();
131 	nMaxHeight = GetSizePixel().Height();
132 
133 
134 	InsertSeparator( 0 );
135 	InsertWindow( CB_URL, &aUrlCB, 0, 0 );
136 	// we need an item text for accessibility
137 	String sItemText = aUrlCB.GetText();
138 	if ( sItemText.Len() == 0 )
139 		sItemText = aUrlCB.GetQuickHelpText();
140 	if ( sItemText.Len() > 0 )
141 	{
142 		SetItemText( CB_URL, sItemText );
143 		sItemText.Erase();
144 	}
145 	InsertWindow( FT_URL, &aUrlFT, 0, 0 );
146 	InsertSeparator( 0 );
147 	InsertWindow( CB_NAME, &aNameCB, 0, 0 );
148 	sItemText = aNameCB.GetText();
149 	if ( sItemText.Len() == 0 )
150 		sItemText = aNameCB.GetQuickHelpText();
151 	if ( sItemText.Len() > 0 )
152 		SetItemText( CB_NAME, sItemText );
153 
154 	SetSizePixel(CalcWindowSizePixel());	// Groesse initialisieren
155 
156 	nMaxHeight = GetSizePixel().Height();	// Hoehe nochmal merken, da sie veraendert wurde
157 											// SetSizePixel ruft Resize-Handler!
158 
159     Show();
160 	Resize();
161 
162 	long nUrlWidth = aUrlCB.GetResizeWidth();
163 	long nNameWidth = aNameCB.GetResizeWidth();
164 	long nSum = nUrlWidth + nNameWidth;
165 
166 	aUrlCB.SetRatio((nUrlWidth * 100L) / nSum);
167 	aNameCB.SetRatio((nNameWidth * 100L) / nSum);
168 
169 	SetClickHdl( LINK( this, SvxHyperlinkDlg, TBClickHdl ) );
170 	SetSelectHdl( LINK( this, SvxHyperlinkDlg, TBSelectHdl ) );
171     SetDropdownClickHdl( LINK( this, SvxHyperlinkDlg, DropdownClick ) );
172 
173     SetItemBits( BTN_TARGET, GetItemBits( BTN_TARGET ) | TIB_DROPDOWNONLY );
174     SetItemBits( BTN_INET_SEARCH, GetItemBits( BTN_INET_SEARCH ) | TIB_DROPDOWN );
175     SetItemBits( BTN_INET_SEARCH, GetItemBits( BTN_TARGET ) | TIB_DROPDOWNONLY );
176 
177 	aLinkPopup.SetSelectHdl(LINK(this, SvxHyperlinkDlg, LinkPopupSelectHdl));
178 
179 	Link aLk = LINK(this, SvxHyperlinkDlg, ComboSelectHdl);
180 	aNameCB.SetSelectHdl(aLk);
181 	aUrlCB.SetSelectHdl(aLk);
182 
183 	aLk = LINK(this, SvxHyperlinkDlg, ComboModifyHdl);
184 	aNameCB.SetModifyHdl(aLk);
185 	aUrlCB.SetModifyHdl(aLk);
186 
187     // Accessibility: Set the quick help text as accessible name for the
188     // drop down lists.
189     aNameCB.SetAccessibleName (aNameCB.GetQuickHelpText());
190     aUrlCB.SetAccessibleName (aUrlCB.GetQuickHelpText());
191 
192     // Hide button according to config item.
193     SvtCommandOptions aCmdOpts;
194     if ( aCmdOpts.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
195                           rtl::OUString(
196                               RTL_CONSTASCII_USTRINGPARAM(
197                                   "InternetSearch" ) ) ) )
198         HideItem( BTN_INET_SEARCH );
199 }
200 
201 /*--------------------------------------------------------------------
202 	Beschreibung:
203  --------------------------------------------------------------------*/
204 
205 SvxHyperlinkDlg::~SvxHyperlinkDlg()
206 {
207     SfxImageManager::GetImageManager( 0 )->ReleaseToolBox(this);
208 
209     if (pTargetMenu != NULL)
210 		delete pTargetMenu;
211 }
212 
213 /*--------------------------------------------------------------------
214 	Beschreibung: Leiste so resizen, dass die Comboboxen automatisch mit
215 	verkleinert werden
216  --------------------------------------------------------------------*/
217 
218 void SvxHyperlinkDlg::Resize()
219 {
220 	long nWidth = GetSizePixel().Width();
221 
222 	ToolBox::Resize();
223 
224 	if (nWidth)	// nWidth ist manchmal 0
225 	{
226 		long nDeltaW = nMaxWidth - nWidth + aUrlCB.LogicToPixel(Size(3, 1)).Width() + 1;
227 
228 		long nNewUrlWidth = aUrlCB.CalcResizeWidth(nDeltaW);
229 		long nNewNameWidth = aNameCB.CalcResizeWidth(nDeltaW);
230 
231 		if (nNewUrlWidth && nNewNameWidth)	// Flackern reduzieren
232 		{
233 			SetUpdateMode(sal_False);
234 
235 			// Comboboxen resizen
236 			aUrlCB.DoResize(nNewUrlWidth);
237 			aNameCB.DoResize(nNewNameWidth);
238 			RecalcItems();	// Alle Elemente neu anordnen
239 
240 			SetUpdateMode(sal_True);
241 		}
242 	}
243 }
244 
245 /*--------------------------------------------------------------------
246 	Beschreibung:
247  --------------------------------------------------------------------*/
248 
249 void SvxHyperlinkDlg::Resizing(Size& rSize)
250 {
251 	if (rSize.Height() > nMaxHeight)
252 		rSize.Height() = nMaxHeight;
253 
254 	if (rSize.Width() > nMaxWidth)
255 		rSize.Width() = nMaxWidth;
256 
257 	ToolBox::Resizing(rSize);
258 }
259 
260 /*--------------------------------------------------------------------
261 	Beschreibung: Im Dokument selektierten Hyperlink in Leiste anzeigen
262  --------------------------------------------------------------------*/
263 
264 void SvxHyperlinkDlg::StateChanged( sal_uInt16 nSID, SfxItemState eState,
265 													const SfxPoolItem* pState )
266 {
267 	if ( nSID == SID_HYPERLINK_DIALOG )
268 	{
269 		if( eState != SFX_ITEM_DISABLED)
270 		{
271 			EnableItem( BTN_OPENDIALOG, sal_True );
272 
273 			sal_Bool bItem = sal_False;
274 			if ( pState && eState == SFX_ITEM_AVAILABLE )
275 					bItem = ((SfxBoolItem*)pState)->GetValue();
276 			SetItemState ( BTN_OPENDIALOG, bItem ? STATE_CHECK : STATE_NOCHECK );
277 		}
278 		else
279 		{
280 			SetItemState ( BTN_OPENDIALOG, STATE_NOCHECK );
281 			EnableItem( BTN_OPENDIALOG, sal_False );
282 		}
283 	}
284 
285 	if (nSID == SID_HYPERLINK_SETLINK)
286 	{
287 		if (eState == SFX_ITEM_DISABLED)
288 			bNoDoc = sal_True;
289 		else
290 			bNoDoc = sal_False;
291 		EnableItem(BTN_TARGET, !bNoDoc);
292 		EnableLink();
293 	}
294 
295 	if (nSID == SID_HYPERLINK_GETLINK)
296 	{
297 		if (eState == SFX_ITEM_AVAILABLE)
298 		{
299 			const SvxHyperlinkItem& rHLnkItem = *((const SvxHyperlinkItem*)pState);
300 
301 			sal_uInt16 nNamePos = aNameCB.GetEntryPos(aNameCB.GetText());
302 			sal_uInt16 nUrlPos = aUrlCB.GetEntryPos(aUrlCB.GetText());
303 			sal_uInt16 nNotFound = COMBOBOX_ENTRY_NOTFOUND;
304 
305 			if (!bHasOldName &&
306 				(nNamePos == nNotFound || nUrlPos == nNotFound))
307 			{
308 				sOldName = aNameCB.GetText();
309 				bHasOldName = sal_True;
310 			}
311 			if (rHLnkItem.GetName().Len())
312 			{
313 				aNameCB.SetText(rHLnkItem.GetName());
314 				ComboModifyHdl(&aNameCB);
315 			}
316 			if (rHLnkItem.GetURL().Len() || rHLnkItem.GetName().Len())
317 			{
318 				String sUrl = INetURLObject(rHLnkItem.GetURL()).GetURLNoPass();
319 				aUrlCB.SetText(sUrl);
320 			}
321 			else if (aUrlCB.GetEntryCount())
322 			{	// Letzten Eintrag wieder selektieren
323 				aNameCB.SetText(aNameCB.GetEntry(0));
324 				aUrlCB.SetText(aUrlCB.GetEntry(0));
325 			}
326 
327 			TargetMenu(rHLnkItem.GetTargetFrame(), sal_False);
328 			bHtmlMode = (rHLnkItem.GetInsertMode() & HLINK_HTMLMODE) != 0;
329 		}
330 		else
331 			return;
332 
333 		ComboModifyHdl(&aUrlCB);
334 	}
335 }
336 
337 /*--------------------------------------------------------------------
338 	Beschreibung:
339  --------------------------------------------------------------------*/
340 
341 IMPL_LINK( SvxHyperlinkDlg, TBClickHdl, ToolBox *, pBox )
342 {
343 	switch (pBox->GetCurItemId())
344 	{
345 		case BTN_LINK:
346 		{
347 			if (!bSend)	// Link ins Dokument einfuegen
348 				SendToApp(HLINK_DEFAULT);
349 		}
350 		break;
351 
352 		case BTN_OPENDIALOG:
353 		{
354 			GetBindings().GetDispatcher()->Execute( SID_HYPERLINK_DIALOG );
355 		}
356 		break;
357 	}
358 
359 	return sal_True;
360 }
361 
362 /*--------------------------------------------------------------------
363 	Beschreibung:
364  --------------------------------------------------------------------*/
365 
366 IMPL_LINK( SvxHyperlinkDlg, TBSelectHdl, ToolBox *, pBox )
367 {
368 	switch (pBox->GetCurItemId())
369 	{
370 		// Link als Bookmark im Explorer eintragen
371 		// Soll erst im Loslassen der Maus gerufen werden, daher im Select-Hdl
372 		case BTN_INSERT_BOOKMARK:
373 		{
374 			String sName = aNameCB.GetText();
375 			if ( !sName.Len() )
376 				sName = aUrlCB.GetText();
377 
378             String aBase = GetBindings().GetDispatcher()->GetFrame()->GetObjectShell()->GetMedium()->GetBaseURL();
379 			SfxStringItem aName( SID_BOOKMARK_TITLE, sName );
380 			SfxStringItem aURL( SID_BOOKMARK_URL,
381                                 URIHelper::SmartRel2Abs( INetURLObject(aBase), aUrlCB.GetText(), URIHelper::GetMaybeFileHdl(), true, false,
382 														  INetURLObject::WAS_ENCODED,
383 														  INetURLObject::DECODE_UNAMBIGUOUS ) );
384 			GetBindings().GetDispatcher()->Execute(
385 				SID_CREATELINK, SFX_CALLMODE_ASYNCHRON, &aName, &aURL, 0L );
386 		}
387 		break;
388 	}
389 
390 	return sal_True;
391 }
392 
393 IMPL_LINK( SvxHyperlinkDlg, DropdownClick, ToolBox *, pBox )
394 {
395 	switch (pBox->GetCurItemId())
396     {
397 		case BTN_LINK:
398 		{
399 			// Link-Popup anstossen
400 	        EndSelection();	// Vor dem Execute, damit Popup den Focus bekommt
401 	        aLinkPopup.EnableItem(MN_BUTTON, !bHtmlMode);
402 	        aLinkPopup.Execute( this, GetItemRect( BTN_LINK ), FLOATWIN_POPUPMODE_DOWN );
403 		}
404 		break;
405 
406 		case BTN_INET_SEARCH:
407 		{
408 			// Search-Engines per Popup auswaehlen
409 			PopupMenu *pMenu = new PopupMenu;
410 			pMenu->SetSelectHdl(LINK(this, SvxHyperlinkDlg, SearchPopupSelectHdl));
411             SearchDefaultConfigItem_Impl aDefaultEngine;
412             String sDefault(aDefaultEngine.GetDefaultSearchEngine());
413             sDefault.ToLowerAscii();
414             const bool bHasDefault = sDefault.Len() > 0;
415 
416             sal_uInt16         nCount = aSearchConfig.Count();
417 			String sFound;
418             for (sal_uInt16 i = 0; i < nCount; i++)
419             {
420                 const SvxSearchEngineData& rData = aSearchConfig.GetData(i);
421                 //check if it's the configured default search engine
422                 String sTest(rData.sEngineName);
423                 sTest.ToLowerAscii();
424                 bool bIsDefaultEngine = bHasDefault && STRING_NOTFOUND != sTest.Search( sDefault );
425                 //then put it at the top
426                 if(i && bIsDefaultEngine)
427                 {
428                     pMenu->InsertItem( i + 1, rData.sEngineName, 0, 0);
429                     pMenu->InsertSeparator(1);
430                 }
431                 else
432                 {
433                     if (i)
434                         pMenu->InsertSeparator();
435                     pMenu->InsertItem( i + 1, rData.sEngineName);
436                 }
437             }
438             pBox->SetItemDown(BTN_INET_SEARCH, sal_True, sal_True);
439             pMenu->Execute( this, GetItemRect( BTN_INET_SEARCH ), FLOATWIN_POPUPMODE_DOWN );
440             pBox->SetItemDown(BTN_INET_SEARCH, sal_False, sal_True);
441             EndSelection();
442 			delete pMenu;
443 		}
444 		break;
445 
446         case BTN_TARGET:
447 		{
448 			// Target Frame einstellen
449 			TargetMenu(GetSelTarget(), sal_True);
450 			EndSelection();
451 		}
452 		break;
453     }
454 
455 	return sal_True;
456 }
457 
458 /*--------------------------------------------------------------------
459 	Beschreibung:
460  --------------------------------------------------------------------*/
461 
462 void SvxHyperlinkDlg::TargetMenu(const String& rSelEntry, sal_Bool bExecute)
463 {
464 	if (pTargetMenu && !bExecute)
465 	{
466 		for (sal_uInt16 i = 1; i <= pTargetMenu->GetItemCount(); i++)
467 		{
468 			if (pTargetMenu->GetItemText(i) == rSelEntry)
469 			{
470 				pTargetMenu->CheckItem(i);
471 				return;
472 			}
473 		}
474 	}
475 
476 	SfxViewFrame* pVwFrm = SfxViewFrame::Current();
477 
478 	if (pVwFrm)	// Alle moeglichen Target Frames zusammensammeln und anzeigen
479 	{
480 		TargetList aList;
481 		pVwFrm->GetTopFrame().GetTargetList(aList);
482 
483 		sal_uInt16 nCount = (sal_uInt16)aList.Count();
484 		if( nCount )
485 		{
486 			sal_Bool bChecked = sal_False;
487 
488 			if (pTargetMenu != NULL)
489 				delete pTargetMenu;
490 
491 			pTargetMenu = new PopupMenu;
492 			pTargetMenu->SetMenuFlags( pTargetMenu->GetMenuFlags() |
493 									   MENU_FLAG_NOAUTOMNEMONICS );
494 			sal_uInt16 i;
495 			for ( i = 0; i < nCount; i++ )
496 			{
497 				String sEntry(*aList.GetObject(i));
498 				pTargetMenu->InsertItem(i + 1, sEntry, MIB_RADIOCHECK|MIB_AUTOCHECK);
499 
500 				if (sEntry == rSelEntry)
501 				{
502 					pTargetMenu->CheckItem(i + 1);
503 					bChecked = sal_True;
504 				}
505 			}
506 			for ( i = nCount; i; i-- )
507 				delete aList.GetObject( i - 1 );
508 
509 			if (!bChecked)
510 				pTargetMenu->CheckItem(1);
511 
512 			if (bExecute)
513 			{
514 				sal_uInt16 nEntry = pTargetMenu->Execute(
515 					this, GetItemRect( BTN_TARGET ), FLOATWIN_POPUPMODE_DOWN );
516 				if ( nEntry )
517 					pTargetMenu->CheckItem( nEntry );
518 			}
519 		}
520 	}
521 }
522 
523 /*--------------------------------------------------------------------
524 	Beschreibung:
525  --------------------------------------------------------------------*/
526 
527 IMPL_LINK( SvxHyperlinkDlg, LinkPopupSelectHdl, Menu *, pMenu )
528 {
529 	switch (pMenu->GetCurItemId())
530 	{
531 		case MN_FIELD:	// URL als Hyperlink ins Dok einfuegen
532 			SendToApp(HLINK_FIELD);
533 			break;
534 		case MN_BUTTON:	// URL als Button ins Dok einfuegen
535 			SendToApp(HLINK_BUTTON);
536 			break;
537 	}
538 
539 	return sal_True;
540 }
541 
542 /*--------------------------------------------------------------------
543 	Beschreibung:
544  --------------------------------------------------------------------*/
545 
546 IMPL_LINK( SvxHyperlinkDlg, SearchPopupSelectHdl, Menu *, pMenu )
547 {
548     const SvxSearchEngineData&  rData = aSearchConfig.GetData(pMenu->GetCurItemId() - 1);
549     String sText(aNameCB.GetText());
550     sText.EraseLeadingChars().EraseTrailingChars();
551 
552     rtl::OUString   sPrefix;
553     rtl::OUString   sSuffix;
554     rtl::OUString   sSeparator;
555     sal_Int32       nCaseMatch;
556     sal_Unicode cToken = 0;
557 
558     if (sText.Search(' ') != STRING_NOTFOUND)
559     {
560         sPrefix = rData.sExactPrefix;
561         sSuffix = rData.sExactSuffix;
562         sSeparator = rData.sExactSeparator;
563         nCaseMatch = rData.nExactCaseMatch;
564         cToken = ' ';
565     }
566     else if (sText.Search('+') != STRING_NOTFOUND)
567     {
568         sPrefix = rData.sAndPrefix;
569         sSuffix = rData.sAndSuffix;
570         sSeparator = rData.sAndSeparator;
571         nCaseMatch = rData.nAndCaseMatch;
572         cToken = '+';
573     }
574     else if (sText.Search(',') != STRING_NOTFOUND)
575     {
576         sPrefix = rData.sOrPrefix;
577         sSuffix = rData.sOrSuffix;
578         sSeparator = rData.sOrSeparator;
579         nCaseMatch = rData.nOrCaseMatch;
580         cToken = ',';
581     }
582     else
583     {
584         sPrefix = rData.sExactPrefix;
585         sSuffix = rData.sExactSuffix;
586         nCaseMatch = rData.nExactCaseMatch;
587         cToken = 0;
588     }
589 
590     String sURL = sPrefix;
591 	xub_StrLen nTok;
592 
593     if(1 == nCaseMatch)
594         sText.ToUpperAscii();
595     else if(2 == nCaseMatch)
596         sText.ToLowerAscii();
597 
598     if ((nTok = sText.GetTokenCount(cToken)) > 1)
599 	{
600 		for (sal_uInt16 i = 0; i < nTok; i++)
601 		{
602             sURL += sText.GetToken(i, cToken);
603             if(i < nTok -1)
604                 sURL += (String)sSeparator;
605 		}
606         sURL += (String)sSuffix;
607 	}
608 	else
609 	{
610         sURL += sText;
611         sURL += (String)sSuffix;
612 	}
613     sURL.EraseAllChars();   // remove all spaces
614     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
615     if ( pViewFrame )
616         pViewFrame = pViewFrame->GetTopViewFrame();
617     OpenDoc( sURL, pViewFrame );
618 
619     return sal_True;
620 }
621 
622 /*--------------------------------------------------------------------
623 	Beschreibung:
624  --------------------------------------------------------------------*/
625 
626 IMPL_LINK( SvxHyperlinkDlg, BookmarkFoundHdl, String *, pUrl )
627 {
628 	if (pUrl && pUrl->Len())
629 	{
630 		aUrlCB.SetText(*pUrl);
631 		ComboModifyHdl(&aUrlCB);
632 	}
633 
634 	return sal_True;
635 }
636 /*--------------------------------------------------------------------
637 	Beschreibung: Link-Button enablen/disablen
638  --------------------------------------------------------------------*/
639 
640 void SvxHyperlinkDlg::EnableLink()
641 {
642 	sal_Bool bEnable = aUrlCB.GetText().Len() != 0;
643 
644 	EnableItem(BTN_LINK, (!bNoDoc) & bEnable);
645 }
646 
647 /*--------------------------------------------------------------------
648 	Beschreibung: URL im Dokument einfuegen
649  --------------------------------------------------------------------*/
650 
651 void SvxHyperlinkDlg::SendToApp(sal_uInt16 nType)
652 {
653 	sal_Bool bIsFile = sal_False;
654 	bSend = sal_True;
655 	String sURL( aUrlCB.GetText() );
656 
657 	if ( !sURL.Len() )
658 		return;
659 
660     String aBase = GetBindings().GetDispatcher()->GetFrame()->GetObjectShell()->GetMedium()->GetBaseURL();
661     INetURLObject aObj( URIHelper::SmartRel2Abs( INetURLObject(aBase), sURL, URIHelper::GetMaybeFileHdl(), true, false,
662 												  INetURLObject::WAS_ENCODED,
663 												  INetURLObject::DECODE_UNAMBIGUOUS ) );
664 	sURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
665 	if ( aObj.GetProtocol() == INET_PROT_FILE )
666 		bIsFile = sal_True;
667 
668 	if ( bIsFile )
669 	{
670 		EnterWait();
671 		SfxMedium aMedium( sURL, STREAM_STD_READ, sal_True );
672 		if ( aMedium.Exists( sal_False ) == sal_False )
673 		{
674 			LeaveWait();
675 			QueryBox aBox( this, SVX_RES( RID_SVXQB_DONTEXIST ) );
676 			if ( aBox.Execute() == RET_NO )
677 				return;
678 		}
679 		else
680 			LeaveWait();
681 	}
682 
683 	SvxHyperlinkItem aItem( SID_HYPERLINK_SETLINK );
684 
685 	if (aNameCB.GetText().Len())
686 		aItem.SetName( aNameCB.GetText() );
687 	else
688 		aItem.SetName( sURL );
689 
690 	sOldName = aNameCB.GetText();
691 
692 	aItem.SetURL(sURL);
693 	aItem.SetInsertMode( (SvxLinkInsertMode)nType );
694 	aItem.SetTargetFrame( GetSelTarget() );
695 
696 	GetBindings().GetDispatcher()->Execute(
697 		SID_HYPERLINK_SETLINK, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L );
698 
699 	AddToHistory( aNameCB.GetText(), sURL );
700 
701 	if ( sURL != aUrlCB.GetText() )
702 		aUrlCB.SetText( sURL );
703 }
704 
705 /*--------------------------------------------------------------------
706 	Beschreibung: Selektierten Target Frame Eintrag im Popup ermitteln
707  --------------------------------------------------------------------*/
708 
709 String SvxHyperlinkDlg::GetSelTarget()
710 {
711 	String sTarget;
712 
713 	if (pTargetMenu != NULL)
714 	{
715 		for (sal_uInt16 i = 1; i <= pTargetMenu->GetItemCount(); i++)
716 		{
717 			if (pTargetMenu->IsItemChecked(i))
718 			{
719 				sTarget = pTargetMenu->GetItemText(i);
720 				break;
721 			}
722 		}
723 	}
724 
725 	return sTarget;
726 }
727 
728 /*--------------------------------------------------------------------
729 	Beschreibung: URL in History der Leiste aufnehmen
730  --------------------------------------------------------------------*/
731 
732 void SvxHyperlinkDlg::AddToHistory(const String& rName, const String& rURL)
733 {
734 	String sName(rName);
735 
736 	if (bHasOldName && sOldName.Len())
737 	{
738 		sName = sOldName;
739 		bHasOldName = sal_False;
740 	}
741 
742 	if (!sName.Len())
743 		sName = rURL;
744 
745 	if (rURL.Len())
746 	{
747 		sal_uInt16 nNamePos = aNameCB.GetEntryPos(sName);
748 		sal_uInt16 nUrlPos = aUrlCB.GetEntryPos(rURL);
749 		sal_uInt16 nPos = COMBOBOX_ENTRY_NOTFOUND;
750 
751 		if (nNamePos != COMBOBOX_ENTRY_NOTFOUND)
752 			nPos = nNamePos;
753 		else
754 			nPos = nUrlPos;
755 
756 		// Alten Eintrag durch neuen Eintrag ersetzen
757 		if (nPos != COMBOBOX_ENTRY_NOTFOUND)
758 		{
759 			aNameCB.RemoveEntry(nPos);
760 			aUrlCB.RemoveEntry(nPos);
761 			aNameCB.SetText(rName);
762 			aUrlCB.SetText(rURL);
763 		}
764 
765 		aNameCB.InsertEntry(sName, 0);
766 		aUrlCB.InsertEntry(rURL, 0);
767 	}
768 }
769 
770 /*--------------------------------------------------------------------
771 	Beschreibung: Bookmark und Search-Button enablen/disablen
772  --------------------------------------------------------------------*/
773 
774 IMPL_LINK( SvxHyperlinkDlg, ComboSelectHdl, ComboBox *, pCombo )
775 {
776 	sal_uInt16 nPos = pCombo->GetEntryPos(pCombo->GetText());
777 
778 	if (nPos != COMBOBOX_ENTRY_NOTFOUND)
779 	{
780 		aNameCB.SetText(aNameCB.GetEntry(nPos));
781 		aUrlCB.SetText(aUrlCB.GetEntry(nPos));
782 
783 		EnableLink();
784 		EnableItem(BTN_INSERT_BOOKMARK, sal_True);
785 		EnableItem(BTN_INET_SEARCH, sal_True);
786 	}
787 	return sal_True;
788 }
789 
790 /*--------------------------------------------------------------------
791 	Beschreibung:
792  --------------------------------------------------------------------*/
793 
794 IMPL_LINK( SvxHyperlinkDlg, ComboModifyHdl, ComboBox *, pCombo )
795 {
796 	sal_Bool bEnable = sal_True;
797 
798 	if (!pCombo->GetText().Len())
799 		bEnable = sal_False;
800 
801 	if (pCombo == &aNameCB)
802 	{
803 		if (IsItemEnabled(BTN_INET_SEARCH) != bEnable)
804 			EnableItem(BTN_INET_SEARCH, bEnable);
805 	}
806 
807 	EnableLink();
808 
809 	if (aUrlCB.GetText().Len())
810 		bEnable = sal_True;
811 	else
812 		bEnable = sal_False;
813 
814 	if (IsItemEnabled(BTN_INSERT_BOOKMARK) != bEnable)
815 		EnableItem(BTN_INSERT_BOOKMARK, bEnable);
816 
817 	return sal_True;
818 }
819 
820 // --------------------------------------------------------------------
821 
822 void SvxHyperlinkDlg::DataChanged( const DataChangedEvent& rDCEvt )
823 {
824 	ToolBox::DataChanged( rDCEvt );
825 
826 	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE))
827 		SetImages();
828 }
829 
830 // --------------------------------------------------------------------
831 
832 void SvxHyperlinkDlg::SetImages()
833 {
834 	bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
835 
836 	SetItemImage( BTN_LINK, mpManager->GetImage( BTN_LINK, bHighContrast ) );
837 	SetItemImage( BTN_INSERT_BOOKMARK, mpManager->GetImage( BTN_INSERT_BOOKMARK, bHighContrast ) );
838 	SetItemImage( BTN_INET_SEARCH, mpManager->GetImage( BTN_INET_SEARCH, bHighContrast ) );
839 	SetItemImage( BTN_TARGET, mpManager->GetImage( BTN_TARGET, bHighContrast ) );
840 	SetItemImage( BTN_OPENDIALOG, mpManager->GetImage( BTN_OPENDIALOG, bHighContrast ) );
841 }
842 
843 /*--------------------------------------------------------------------
844 	Beschreibung: Comboboxen
845  --------------------------------------------------------------------*/
846 
847 HyperCombo::HyperCombo( SvxHyperlinkDlg* pDialog, const ResId& rResId ) :
848 		ComboBox( (Window *)pDialog, rResId )
849 {
850 	pDlg = pDialog;
851 
852 	nMaxWidth = GetSizePixel().Width();
853 	if (this == &pDlg->aUrlCB)
854 		nMinWidth = GetTextWidth(String::CreateFromAscii("http://www.stardiv.dewww"));
855 	else
856 		nMinWidth = GetTextWidth(String::CreateFromAscii("StarDivision GmbHwww"));
857 }
858 
859 /*--------------------------------------------------------------------
860 	Beschreibung: Comboboxen KeyInput
861  --------------------------------------------------------------------*/
862 
863 long HyperCombo::Notify( NotifyEvent& rNEvt )
864 {
865 	long nHandled = 0;
866 	static sal_Bool bLocked = sal_False;
867 
868 	if (bLocked)	// Keine weiteren RETURNs annehmen (nicht Reentrant!)
869 		return nHandled;
870 
871 	bLocked = sal_True;
872 
873 	if ( rNEvt.GetType() == EVENT_KEYINPUT )
874 	{
875 		const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
876 		const KeyCode aKeyCode = pKEvt->GetKeyCode();
877 
878 		if (aKeyCode.GetCode() == KEY_RETURN)
879 		{
880 			pDlg->SendToApp(HLINK_DEFAULT);
881 			nHandled = 1;
882 		}
883 	}
884 	if (this == &pDlg->aNameCB)
885 		pDlg->sOldName = GetText();
886 
887 	if (!nHandled)
888 		nHandled = ComboBox::Notify( rNEvt );
889 
890 	bLocked = sal_False;
891 
892 	return nHandled;
893 }
894 
895 /*--------------------------------------------------------------------
896 	Beschreibung: Drag&Drop vor dem Combo-Edit abfangen und weiterleiten
897  --------------------------------------------------------------------*/
898 
899 long HyperCombo::PreNotify( NotifyEvent& rNEvt )
900 {
901 	long nHandled = 0;
902 
903 	nHandled = ComboBox::PreNotify( rNEvt );
904 
905 	return nHandled;
906 }
907 
908 /*--------------------------------------------------------------------
909 	Beschreibung:
910  --------------------------------------------------------------------*/
911 
912 long HyperCombo::CalcResizeWidth( long nW )
913 {
914 	long nNewWidth = Max(nMaxWidth - nW * GetRatio() / 100L, nMinWidth);
915 
916 	if (nNewWidth > nMaxWidth)
917 		nNewWidth = nMaxWidth;
918 
919 	if (nNewWidth != GetSizePixel().Width())
920 		return nNewWidth;
921 	else
922 		return 0;	// Kein Resize notwendig
923 }
924 
925 /*--------------------------------------------------------------------
926 	Beschreibung:
927  --------------------------------------------------------------------*/
928 
929 void HyperCombo::DoResize( long nNewWidth )
930 {
931 	SetSizePixel(Size(nNewWidth, GetSizePixel().Height()));
932 }
933 
934 /*--------------------------------------------------------------------
935 	Beschreibung: FixedText
936  --------------------------------------------------------------------*/
937 
938 HyperFixedText::HyperFixedText( SvxHyperlinkDlg* pDialog, const ResId& rResId ) :
939 		FixedInfo( (Window *)pDialog, rResId )
940 {
941 	pDlg = pDialog;
942 }
943 
944 /*--------------------------------------------------------------------
945 	Beschreibung: Webseite der Search-Engine mit Suchergebnissen anzeigen
946  --------------------------------------------------------------------*/
947 void SvxHyperlinkDlg::OpenDoc( const String& rURL, SfxViewFrame* pViewFrame )
948 {
949 	SfxStringItem aName( SID_FILE_NAME, rURL );
950 	SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii("private:user") );
951     SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_True );
952 	SfxBoolItem aSilent( SID_SILENT, sal_True );
953 	SfxBoolItem aReadOnly( SID_DOC_READONLY, sal_True );
954     SfxBoolItem aExternal( SID_BROWSE, sal_True );
955     SfxDispatcher* pDisp = SfxViewFrame::Current() ? SfxViewFrame::Current()->GetDispatcher() : NULL;
956 
957 	if ( pViewFrame )
958 	{
959 		SfxFrameItem aView( SID_DOCFRAME, pViewFrame ? &pViewFrame->GetFrame() : NULL );
960 		if ( pDisp )
961 			pDisp->Execute( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
962                             &aName, &aView, &aNewView, &aSilent, &aReadOnly, &aReferer, &aExternal, 0L );
963 	}
964 	else if ( pDisp )
965 		pDisp->Execute( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
966 						&aName, &aNewView, &aSilent, &aReadOnly, &aReferer, 0L );
967 }
968 // class SvxHyperlinkDialogWrapper ------------------------------------------
969 
970 SFX_IMPL_CHILDWINDOW(SvxHyperlinkDlgWrapper, SID_HYPERLINK_INSERT)
971 
972 /*--------------------------------------------------------------------
973 	Beschreibung: Wrapper fuer Hyperlinkleiste
974  --------------------------------------------------------------------*/
975 
976 SvxHyperlinkDlgWrapper::SvxHyperlinkDlgWrapper( Window* _pParent, sal_uInt16 nId,
977                                                 SfxBindings* _pBindings, SfxChildWinInfo* /*pInfo*/ ) :
978 
979     SfxChildWindow( _pParent, nId )
980 
981 {
982     pWindow = new SvxHyperlinkDlg( _pBindings, _pParent );
983 	eChildAlignment = SFX_ALIGN_TOP;
984 }
985 
986 /*--------------------------------------------------------------------
987 	Beschreibung:
988  --------------------------------------------------------------------*/
989 
990 SfxChildWinInfo SvxHyperlinkDlgWrapper::GetInfo() const
991 {
992 	SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
993 	return aInfo;
994 }
995 
996